题目这边;http://poj.org/problem?id=2184

01背包的变形

有n个cow,每个cow有两个值,一个a值一个b值,要求a值之和和b值之和都不能为负数,问最大的a+b值之和是多少,如样例就是选择了第1,3,4头cow,最大为8

可以将其中一个值比如a值当成背包容量,b值当成价值,取一个极限值当做0,负的a值在极限值左边,正的a值在极限值右边,这样解决了负数的问题,筛选背包值为正和

容量值不小于极限值就解决了a值和b值和部位负的问题

 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #define inf 0x3f3f3f
 5 using namespace std;
 6 int main()
 7 {
 8     int t,i,j,sum;
 9     int w[200],d[200];
10     int dp[200001];
11     while (~scanf("%d",&t))
12     {
13         for (i=1;i<=t;i++)
14             scanf("%d %d",&w[i],&d[i]);
15         memset(dp,-inf,sizeof(dp));
16         dp[100000]=0;
17         for (i=1;i<=t;i++)
18         {
19             if (w[i]<0&&d[i]<0)
20                 continue;
21             if (w[i]>0)
22             {
23                 for (j=200000;j>=w[i];j--)
24                 {
25                    if (dp[j-w[i]]>-inf)
26                       dp[j]=max(dp[j],dp[j-w[i]]+d[i]);
27                 }
28             }
29             else
30             {
31                 for (j=w[i];j<=200000+w[i];j++)
32                 {
33                     if (dp[j-w[i]]>-inf)
34                         dp[j]=max(dp[j],dp[j-w[i]]+d[i]);
35                 }
36             }
37         }
38         sum=-inf;
39         for (i=100000;i<=200000;i++)
40         {
41                 if(dp[i]>=0)
42                     sum=max(sum,dp[i]+i-100000);
43         }
44         printf("%d\n",sum);
45     }
46     return 0;
47 }

 

posted on 2015-10-17 20:11  蜘蛛侦探  阅读(339)  评论(0编辑  收藏  举报