关于这个背包问题,我弄了好久了,现在终于有一点想法了。
先说最简单的0-1背包问题:
假如我们有n件物品(用i来表示 1=<i<=n),每一件物品价值分别为value[i],重量分别为wight[i],
背包的容量为C,要我们从中选几件物品,在背包的容量范围内使得总的价值最大。
对于这种问题,我们得分阶段来考虑,每一个阶段选择一个物品:
我们用V[i][S] 来表示在第 i 阶段,容量为S的状态下,我们能获得的最大价值。显然它是由上一阶段
来得到的:
V[i][S] = max{V[i-1][S] , V[i-1][S-wight[i]] + value[i]}
其实以上方程可以化简成一维的:即V[i] = max{V[i] , V[i-wight[i]]+value[i]} (i = C,C-1,C-2,.....0)
伪代码如下:
for(int i=1;i<=C;++i)
v[i] = 0;
for(int i=1;i<=n;++i)
for(int s = n;s>=wight[i];--s)
if(V[s-wight[i]] + value[i] > V[s])
V[s] = V[s-wight[i]] + value[i];
以上是背包问题中最简单的问题,在这基础上还有一个完全背包问题,就是对于这n种物品中的每一
种,我们都可以无限的去取,我们扔然可以按照0-1背包的思路去写出状态转移方程:
令f[i][v]表示前i种物品恰放入一个容量为v的背包的最大权值:
f[i][v]=max{f[i-1][v-k*c[i]]+k*w[i]|0<=k*c[i]<=v}
其最简单的算法是:
for i=1,2,...n
for s=0,1,....C
f[v]=max{f[v],f[v-cost]+weight}