题目这边;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 }