标签:class 01背包问题 01背包 要求 inf max out space strong
1 #include<iostream> 2 #include<algorithm> 3 using namespace std; 4 /* 5 f[i][j]表示只看前i个物品,总体积是j的情况下,总价值最大是多少 6 result = f[n]f[v] 7 1.不选第i个物品,f[i][j]=f[i-1][j]; 8 2.选第i个物品,f[i][j]=f[i-1][j-k*v[i]]+k*w[i](v[i]是体积,w[i]是价值,k是物品最大个数) 9 f[0][0]=0; 10 */ 11 const int array_size = 1001; 12 int f[array_size][array_size], v[array_size], w[array_size], N, V; 13 int main() { 14 cin >> N >> V; 15 for (int i = 1; i <= N; ++i) { 16 cin >> v[i] >> w[i]; 17 for (int j = 0; j <= V; ++j) { 18 f[i][j] = f[i - 1][j]; 19 for (int k = 1; k <= j / v[i]; ++k) 20 if (j >= k*v[i]) 21 f[i][j] = max(f[i][j], f[i - 1][j - k*v[i]] + k*w[i]); 22 } 23 24 } 25 cout << f[N][V]; 26 }
#include<iostream> #include<algorithm> using namespace std; const int array_size = 1001; int f[array_size], v[array_size], w[array_size], N, V; int main() { cin >> N >> V; for (int i = 1; i <= N; ++i) { cin >> v[i] >> w[i]; /* 相当于01背包问题换了j的遍历顺序,结果就是第i轮(前i个物品) 中,先算f[j-v[i]],再算f[j] 数学归纳法证明优化后算法成立: 1、前1个物品中:f[1]=2,f[2]=4,f[3]=6,f[4]=8,f[5]=10,显然f[j]都是正确的。 2、假设在前i-1个物品中,f[j]都是正确的。 3、前i个物品中,对于某个j而言,如果最优解包含k个v[i],则一定会枚举到f[j-k*v[i]] f[j-k*v[i]]是如何得到的呢?f[j-k*v[i]]=max{f[j-k*v[i]],f[j-k*v[i]-v[i]]+w[i]} (由于j正序,f[j-k*v[i]]为前i-1个物品的值,f[j-k*v[i]-v[i]]为前i个物品的值) 最后会传递到max{f[v[i]],f[0]+w[i]}处。因为f[v[i]]一定正确(2中已假设前i-1个物品 中的f[j]全都正确),f[0]一定正确(=0),w[i]一定正确,所以max{f[v[i]],f[0]+w[i]} 一定正确=>f[j-k*v[i]]一定正确=>f[j]一定正确。 综上,证明成立。 */ for (int j = v[i]; j <= V; ++j) f[j] = max(f[j], f[j -v[i]] + w[i]); } cout << f[V]; } /* 若是要求物品恰好装满背包时的最大价值,只需 初始化时将f[0]置0,f[1]-f[V]都置-INF就可以了。 确保所有状态都是由f[0]转移过来。 */
标签:class 01背包问题 01背包 要求 inf max out space strong
原文地址:https://www.cnblogs.com/xiehuazhen/p/12464732.html