51nod 1085背包问题
#include<iostream>
using namespace std;
int V[101][10001];
int main()
{int N,W;
cin>>N>>W;
int w[101],p[101]; //需要注意数组范围的限定,题目要求N从一开始
for(int i=1;i<=N;i++)
cin>>w[i]>>p[i];
for(int i=1;i<=N;i++)
for(int j=0;j<=W;j++) //体积可能为0
if(j<w[i]) V[i][j]=V[i-1][j];
else
V[i][j]=max(V[i-1][j],V[i-1][j-w[i]]+p[i]);
cout<<V[N][W];
}
寻找递推关系式,面对当前商品有两种可能性:
第一,包的容量比该商品体积小,装不下,此时的价值与前i-1个的价值是一样的,即V(i,j)=V(i-1,j);
第二,还有足够的容量可以装该商品,但装了也不一定达到当前最优价值,所以在装与不装之间选择最优的一个,即V(i,j)=max{ V(i-1,j),V(i-1,j-w(i))+v(i) }
其中V(i-1,j)表示不装,V(i-1,j-w(i))+v(i) 表示装了第i个商品,背包容量减少w(i)但价值增加了v(i);
由此可以得出递推关系式:
1) j<w(i) V(i,j)=V(i-1,j)
2) j>=w(i) V(i,j)=max{ V(i-1,j),V(i-1,j-w(i))+v(i) }
g) 填表,首先初始化边界条件,V(0,j)=V(i,0)=0;

h) 然后一行一行的填表,
1) 如,i=1,j=1,w(1)=2,v(1)=3,有j<w(1),故V(1,1)=V(1-1,1)=0;
2) 又如i=1,j=2,w(1)=2,v(1)=3,有j=w(1),故V(1,2)=max{ V(1-1,2),V(1-1,2-w(1))+v(1) }=max{0,0+3}=3;
3) 如此下去,填到最后一个,i=4,j=8,w(4)=5,v(4)=6,有j>w(4),故V(4,8)=max{ V(4-1,8),V(4-1,8-w(4))+v(4) }=max{9,4+6}=10;所以填完表如下图:


浙公网安备 33010602011771号