先将原始问题一般化,欲求背包能够获得的总价值,即欲求前j个物体放入容量为m(kg)背包的最大价值f[j]——使用一个数组来存储最大价值,当j取10时,即原始问题了。而前i个物体放入容量为m(kg)的背包,又可以转化成前(i-1)个物体放入背包的问题。
核心代码:
for(i=0;i
f[j]=max(f[j],f[j-bone[i].volume]+bone[i].value);
f[j]=max(f[j],f[j-bone[i].volume]+bone[i].value);即为该问题的状态转移方程
当i==0,bone[0].volume==5时经过一个循环
f[10]=1;
f[9]=1;
f[8]=1;
f[7]=1;
f[6]=1;
f[5]=1;
f[4]=0;
f[3]=0;
f[2]=0;
f[1]=0;
f[0]=0;
当i==1,bone[1].volume==4时经过一个循环
f[10]=3;
f[9]=3;
f[8]=2;//因为飞f[4]==0,f[8]==1,而8-bone[1].volume==4,所以f[8]=max(f[8],f[j-bone[i].volume(4)]+bone[i].value(2));下面同理
f[7]=2;
f[6]=2;
f[5]=2;
f[4]=2;
f[3]=0;//3<5也<4,所以前两个骨头都放不下,下面同理,上面也同理
f[2]=0;
f[1]=0;
f[0]=0;
当i==2,bone[2].volume==3时经过一个循环
f[10]=5;
f[9]=5;
f[8]=5;
f[7]=5;
f[6]=3;
f[5]=3;
f[4]=3;
f[3]=3;
f[2]=0;
f[1]=0;
f[0]=0;
当i==3,bone[3].volume==2时经过一个循环
f[10]=9;
f[9]=9;
f[8]=7;
f[7]=7;
f[6]=7;
f[5]=7;
f[4]=4;
f[3]=4;
f[2]=4;;//在此j循环跳出,上面同理,下面也同理,f[j]>=2;
f[1]=0;
f[0]=0;
当i==4,bone[3].volume==1时经过一个循环
f[10]=14;
f[9]=12;
f[8]=12;
f[7]=12;
f[6]=12;
f[5]=9;
f[4]=9;
f[3]=9;
f[2]=5;;//在此j循环跳出,上面同理,下面也同理,f[j]>=2;
f[1]=5;
f[0]=0;
代码实现:
1 #include2 #include 24 cin>>bone[i].value; 25 for(i=0;i3 #include 4 #include 5 using namespace std; 6 struct bone 7 { 8 int volume; 9 int value; 10 }bone[1005]; 11 int max(int a,int b) 12 { 13 return a>b?a:b; 14 } 15 int main() 16 { 17 int t,n,v,i,j,f[1005]; 18 while(cin>>t) 19 { 20 while(t--) 21 { 22 cin>>n>>v; 23 for(i=0;i ) ) 26 cin>>bone[i].volume; 27 memset(f,0,sizeof(f)); 28 for(i=0;i ) 29 for(j=v;j>=bone[i].volume;j--) 30 f[j]=max(f[j],f[j-bone[i].volume]+bone[i].value); 31 cout< endl; 32 } 33 } 34 return 0; 35 }