http://poj.org/problem?id=2184
http://blog.csdn.net/liuqiyao_01/article/details/8753686
对于负体积问题,可以先定义一个“零点”shift,将dp[shift]设为0,其他都设为-INF。
然后负体积从0往maxn+cost更新,正体积从maxn往shift更新。
最后从shift到maxn中找最大值,shift以下的值不会被遍历到
#include <iostream> #include <string> #include <cstring> #include <cstdlib> #include <cstdio> #include <cmath> #include <algorithm> #include <stack> using namespace std; #define MEM(a,b) memset(a,b,sizeof(a)) #define pf printf #define sf scanf #define debug printf("!\n") #define INF (0x3f3f3f3f) #define MAX(a,b) a>b?a:b #define blank pf("\n") #define LL long long #define ep 1e-6 const int shift = 10000; const int MAXN = 210000; const int MAXM = 105; int dp[MAXN]; int ci[MAXM];//容量 int wi[MAXM];//价值 int n,V,i,j,v,t,sum; double G; void zeroOnePack(int cost,int weight) { if(cost>=0) { for(v = MAXN-1;v>=cost;v--) { dp[v] =MAX(dp[v],dp[v-cost]+weight); } } else { for(v = 0;v<MAXN+cost;v++) { dp[v] =MAX(dp[v],dp[v-cost]+weight); } } } int main() { while(sf("%d",&n)!=EOF) { MEM(dp,-INF); MEM(wi,0); for(i = 0;i<n;i++) { sf("%d",&ci[i]); sf("%d",&wi[i]); } dp[shift] = 0; for(i = 0;i<n;i++) { zeroOnePack(ci[i],wi[i]); } int ans = -INF; for(i = shift;i<MAXN;i++) { if(dp[i]>=0 && (i-shift+dp[i])>ans) ans = i-shift+dp[i]; } pf("%d\n",ans); } return 0; } /* 5 -5 7 8 -6 6 -3 2 1 -8 -5 */
时间: 2024-10-17 00:04:13