1 /* 2 有n个物品和一个容量为V的背包,第i件物品的费用是c[i],价值是w[i] 3 求解哪些物品装入背包使价值总和最大 4 dp[i][j] dp[i][j] 为前i件物品放进容量为j的背包的最大价值 5 dp[i][j] = max(dp[i-1][j],dp[i-1][j-c[i]]+w[i]); 6 */ 7 #include <stdio.h> 8 #include <string.h> 9 int dp[111][1111]; 10 int dp2[1001]; 11 int c[111],w[111]; 12 bool flag[111]; 13 inline int max(const int &a, const int &b) 14 { 15 return a < b ? b : a; 16 } 17 int main() 18 { 19 int n,v,i,j; 20 while(scanf("%d%d",&n,&v)!=EOF) 21 { 22 memset(dp,0,sizeof(dp)); 23 dp2[0] = 0; 24 for(i=1; i<=n; ++i) 25 dp2[i] = 1<<30; 26 memset(flag,false,sizeof(flag)); 27 for(i=1; i<=n; ++i) 28 scanf("%d",&w[i]); 29 for(i=1; i<=n; ++i) 30 scanf("%d",&c[i]); 31 for(i=1; i<=n; ++i)//时间空间复杂度均为O(VN) 32 for(j=0; j<=v; ++j) 33 { 34 dp[i][j] = dp[i-1][j]; 35 if(j>=c[i]) 36 dp[i][j] = max(dp[i][j],dp[i-1][j-c[i]]+w[i]); 37 } 38 for(i=1; i<=n; ++i) 39 for(j=v; j>=0; --j) 40 { 41 if(j>=c[i]) 42 dp2[j] = max(dp2[j],dp2[j-c[i]]+w[i]); 43 } 44 printf("%d\n",dp[n][v]); 45 printf("%d\n",dp2[v]); 46 /*时间复杂度不能优化了,但是空间可以优化到O(V) 47 for(i=1; i<=n; ++i) 48 for(j=v; j>=0; --j)//将循环改为这样也是成立的 49 那么每一个dp[i][j] 都是继承自上一层的dp[i-1][j] 或者dp[i-1][j-c[i]] 50 那么j是大于等于j或者j-c[i]的。 51 那么就可以这样 52 for(i=1; i<=n; ++i) 53 for(j=v; j>=c[i]; --j)//必须是从后忘前 54 { 55 dp2[j] = max(dp2[j],dp[j-c[i]+w[i]]);//这一层继承继承自上一层,这种数组叫做滚动数组 56 } 57 */ 58 //下面是判断哪几个背包被选 59 int Max = dp[n][v]; 60 for(i=n; i>=1; --i) 61 { 62 if(dp[i-1][v]>= Max) 63 flag[i] = false; 64 else 65 { 66 flag[i] = true; 67 v -= c[i]; 68 Max -= w[i]; 69 } 70 } 71 if(flag[1]) 72 printf("1"); 73 else 74 printf("0"); 75 for(i=2; i<=n; ++i) 76 if(flag[i]) 77 printf(" 1"); 78 else 79 printf(" 0"); 80 printf("\n"); 81 } 82 return 0; 83 } 84 /* 85 5 10 86 6 3 5 4 6 87 2 2 6 5 4 88 Sample Output: 89 15 90 1 1 0 0 1 91 */ 92 /* 93 另外还有就是求背包的最优解过程中,有两种要求: 94 (1)要求背包装满,且价值最大(所以可能导致无解的情况发生) 95 (2)只要求价值最大 96 这两种问法差别在于初始化 97 (1)将dp[0][0]初始化为0,其他的初始化为-INF,这是由题目的性质导致的 98 初始的时候什么都不装,但是背包有容量而没装满是不合法的,所以定义-INF为不合法的 99 如果要求背包装满,那么dp[i][j]表示的含义就变为了前i个物品装满容量为j的背包的最大价值 100 dp[i][j] = max(dp[i-1][j],dp[i-1][j-c[i]]+w[i]); 101 如果dp[i-1][j],dp[i-1][j-c[i]]+w[i] ,这两个状态是不合法的,那么dp[i][j]也是不合法的 102 (2)都初始化为0 103 104 */
时间: 2024-10-30 14:01:32