题目
源地址:
http://codeforces.com/problemset/problem/3/B
理解
读懂题略微花了一点时间,主要是生词多,有点吓人= =。有一辆卡车,要装载一些船只,有1和2两种。然后给出n个船的类型和容积,要求给定卡车体积v的情况下,装载的船的最大容积。 一开始的想法是理解成一个背包问题,但是给的v太大,用DP处理可能会超时。后来就用简单一点的思路,直接暴力贪心。把两种船分开,分别进行排序。小脑一动就能明白,最优解肯定是选取价值高的,然后枚举选择i只1船,则选择2船只的个数就是min((v - i) / 2, tc)其中tc为2船总个数。 输出上有一个trick,就是每个编号之间都有一个空格= =,因此WA一发。。
代码
#define MAXN 100000+10
int sum1[MAXN], sum2[MAXN], oc, tc, ans[MAXN];
int n, v, a, b, maxv, c1, c2;
struct node
{
int id,val;
} one[MAXN], two[MAXN];
bool cmp(node x, node y)
{
return x.val > y.val;
}
void init()
{
scanf("%d%d", &n, &v);
oc = tc = 0;
for(int i=1; i<=n; i++)
{
scanf("%d%d", &a, &b);
if(a == 1)
one[++oc].val = b, one[oc].id = i;
else
two[++tc].val = b, two[tc].id = i;
}
sort(one+1, one + oc + 1, cmp);
sort(two+1, two + tc + 1, cmp);
}
int main(int argc, char const *argv[])
{
init();
sum2[0] = sum1[0] = 0;
for(int i=1; i<=tc; i++) sum2[i] = sum2[i - 1] + two[i].val;
for(int i=1; i<=oc; i++) sum1[i] = sum1[i - 1] + one[i].val;
c1 = -1, c2 = -1, maxv = -1;
for(int i=0; i<=oc; i++)
{
if(i > v)
break;
int d = sum1[i] + sum2[min((v - i) / 2, tc)];
if(d > maxv)
{
maxv = d;
c1 = i;
c2 = min((v - i) / 2, tc);
}
}
if(maxv == -1)
{
printf("0\n");
return 0;
}
int cnt = 0;
printf("%d\n", maxv);
for(int i=1; i<=c1; i++) ans[++cnt] = one[i].id;
for(int i=1; i<=c2; i++) ans[++cnt] = two[i].id;
for(int i=1; i<=cnt; i++)
printf("%d%c", ans[i], i == cnt? '\n' : ' ');
return 0;
}
/*
5 3
1 9
2 9
1 9
2 10
1 6
24
3 1 5
**/
更新日志
- 2014年11月7日 已AC。