关于动态规划的01背包问题,首先对问题进行分析并进行属性的划分:
1.集合的划分,我们可以知道这个药他可以采也可以不采,也就说明现在集合中有两个元素
只考虑前i个物品,总容量不超过T的选法,然后求最大值
2.求最大值,所以属性为max
3.填充完集合和属性之后,我们通过分析可以得到,从0~i挑出<=j的草药来实现价值,每次取完都和a[i-1][j](i-1的意思就是我当前不去取这个草药,那这个地方a[i][j]是空的,不能自己取自己,那样完全没意义,所以我们引用a[i-1][j]来表示[这个是为了好记忆,并不是真的])进行比较。
4.那么如何去取:我们从a[i-1][j-v[i]]中取,你看第二维中j-v[i],就是当前我们还剩下的容量,我们每次采药都要消耗容量吧,而数组中的第二维就是帮助我们解决这个问题的,至于价值我们就可以在后边直接进行添加:a[i-1][j-v[i]]+w[i];
另外需要特判一下,因为你的背包可以装不下此时的草药。
5.我们最后就可以在最后的地方:dp[n][m]中取得最大值。
6.可以通过输出dp的所有内容来检验自己是否正确。
#include<bits/stdc++.h>
using namespace std;
int a[1010];
int w[1010];
int v,m;
int dp[1500][1500];
int main()
{
cin>>v>>m;
for(int i=1;i<=m;i++)
{
cin>>a[i]>>w[i];
}
for(int i=1;i<=m;i++)
{
for(int j=v;j>=1;j--)
{
if(j<a[i])
dp[i][j]=dp[i-1][j];
else
dp[i][j]=max(dp[i-1][j],dp[i-1][j-a[i]]+w[i]);
}
}
// for(int i=1;i<=m;i++)
// {
// for(int j=1;j<=v;j++)
// {
// cout<<dp[i][j]<<" ";
// }
// cout<<endl;
// }
cout<<dp[m][v]<<endl;
return 0;
}