目录
1.分析
设F(i,j)表示放入i个物品且背包剩余为j容量时的最大价值。
a[]为每个物品的大小,v[]为每个物品的价值,m为最大容量。
状态转移方程为:
1.1当放入的物品比剩余容量j大时
F(i,j)=F(i-1,j);
1.2放的下时
这时,我们需要比较是放入该物品价值更大还是不放入该物品价值更大。
由于我们每次只放入一个物品(即将来矩阵中的元素都是最优解),因此放入物品是取出物品再放入还是直接放入都是相同的结论:
F1(i,j)=F(i-1,j-a[i-1])+v[i-1];
不放入物品的结论和放不下是一样的:
F2(i,j)=F(i-1,j);
最终结论即是从F1和F2取出最大的那个:
F(i,j)=max(F1,F2);
给个图看看吧:
注意:由于防止处理第一个物品或较少容量时越界,我们需要将第一列和第一行初始化为0。
2.代码
int backPackII(int m, vector<int> &a, vector<int> &v) {
// write your code here
vector<vector<int>> arr;
//初始化完成
int row=a.size()+1;
arr.resize(row);
for(int i=0;i<row;i++)
{
arr[i].resize(m+1);
}
for(int i=0;i<row;i++)
arr[i][0]=0;
for(int j=0;j<=m;j++)
arr[0][j]=0;
for(int i=1;i<row;i++)
{
for(int j=1;j<=m;j++)
{
if(a[i-1]>j)
arr[i][j]=arr[i-1][j];
else
arr[i][j]=max((arr[i-1][j-a[i-1]]+v[i-1]),arr[i-1][j]);
}
}
return arr[row-1][m];
}
};