题目大意:
有100头牛,每头牛有Fi, Si两个值。Fi, Si 范围是-1000~1000
选出一些牛,确保这些牛的 Sum{Fi} + Sum{Si} 最大
同时 Sum{Fi},Sum{Si} 都不能为负
思路:
一开始看到范围那么大,首先就否决背包了!想了一个不大灵光的解法,结果wa啦。。
后来看了Discuss。发现都是用背包过的,是最简单的一维背包!居然还有人是搜索过的!
但是,如果数据bt点的话,背包是不可能过的!但是USACO的题目感觉数据都弱一点,哈哈!
代码烂,63ms
#include <stdio.h>
struct {
int val, used;
} _slot[100024*2], *slot = &_slot[100024];
int up, down;
int main()
{
int n, s, f, i;
freopen("e:\\test\\in.txt", "r", stdin);
scanf("%d", &n);
up = down = 0;
while (n--) {
scanf("%d%d", &s, &f);
if (s < 0 && f < 0)
continue;
if (s < 0) {
for (i = down; i <= up; i++) {
if (!slot[i].used)
continue;
if (!slot[i + s].used || f + slot[i].val > slot[i + s].val) {
slot[i + s].used = 1;
slot[i + s].val = f + slot[i].val;
}
}
down += s;
} else {
for (i = up; i >= down; i--) {
if (!slot[i].used)
continue;
if (!slot[i + s].used || f + slot[i].val > slot[i + s].val) {
slot[i + s].used = 1;
slot[i + s].val = f + slot[i].val;
}
}
up += s;
}
if (!slot[s].used || slot[s].val < f) {
slot[s].used = 1;
slot[s].val = f;
}
}
s = 0;
for (i = 0; i <= up; i++) {
if (slot[i].used && slot[i].val >= 0 && slot[i].val + i > s)
s = slot[i].val + i;
}
printf("%d\n", s);
return 0;
}