poj2184(01背包变形)

来源:互联网 发布:windows webpack 编辑:程序博客网 时间:2024/04/30 13:11

题目链接:poj2184

/*题意:    有一些牛,每个牛有一个的智商值(用S表示)和幽默度(用F表示)选出若干牛,使S的和非负且F的和非负时,S+F最大思路:    将S当做体积,F当做价值,来装01背包。循环时,体积为负时,循环的方向和体积为正时相反。最多100组,每组-1000~1000,所以体积的范围[-1000*100,1000*100],因为体积有负数存在,所以将整个区间向右平移,平移后范围是[0,200000];原点变为100000*/#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <map>#include <queue>#include <algorithm>using namespace std;const int inf = 0x3f3f3f3f;const int N = 200000;int c[N],w[N];int d[N];int main(){    int n,i,j;    int k = 100000;    while(~scanf("%d",&n))    {        for(i = 0; i < n; i ++)            scanf("%d%d",&c[i],&w[i]);        fill(d, d+N, -inf);        d[k] = 0;        for(i = 0; i < n; i ++)        {            if(c[i] >= 0)                for(j = N-1; j >= c[i]; j --)                    if(d[j-c[i]] > -inf)                        d[j] = max(d[j], d[j-c[i]] + w[i]);            if(c[i] < 0)                for(j = 0; j < N + c[i]; j ++)                    if(d[j-c[i]] > -inf)                        d[j] = max(d[j], d[j-c[i]] + w[i]);        }        int ans = 0;        for(i = k; i < N; i ++)            if(d[i] >= 0)            ans = max(ans, d[i]+(i-k));        printf("%d\n",ans);    }    return 0;}


0 0
原创粉丝点击