有n种物品,每种只有一个。第i种物品的体积为Vi,重量为Wi。选一些物品装到一个容量为C的背包,使得背包内物品在总体积不超过C的前提下尽量大。
思想:f(i,j)表示把前i个物品装到容量为j的背包中的最大总重量,则f(i,j)=max{f(i-1,j),f(i-1,j-V[i])+W[i]}。边界为: i=0时为0,j<0时为负无穷,答案为f(n,C)。
1 for(int i=1; i<=n; i++) 2 for(int j=0; j<=C; j++) 3 { 4 f[i][j] = (i==1 ? 0 : f[i-1][j]); 5 if(j>=V[i]) f[i][j] = max(f[i][j],f[i-1][j-V[i]]+W[i]); 6 }
1 #include <iostream> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cstdio> 5 #include <cmath> 6 #include <climits> 7 #include <queue> 8 #include <stack> 9 #include <algorithm> 10 using namespace std; 11 #define maxn 50 12 int p[maxn]; 13 int v[maxn]; 14 int dp[maxn][30010]; 15 int main() 16 { 17 int cases; 18 scanf("%d",&cases); 19 while(cases--) 20 { 21 int sum; 22 int n; 23 scanf("%d%d",&sum,&n); 24 memset(p,0,sizeof(p)); 25 memset(v,0,sizeof(v)); 26 memset(dp,0,sizeof(dp)); 27 int price; 28 int imp; 29 for(int i=1; i<=n; i++) 30 scanf("%d%d",&p[i],&v[i]); 31 for(int i=1; i<=n; i++) 32 for(int j=0; j<=sum; j++) 33 { 34 dp[i][j] = (i==1?0:dp[i-1][j]); 35 if(j>=p[i]) dp[i][j] = max(dp[i][j],dp[i-1][j-p[i]]+p[i]*v[i]); 36 } 37 printf("%d\n",dp[n][sum]); 38 } 39 return 0; 40 }