初学算法的我
今天差不多看了一个半小时01背包,终于研究明白了。
赶紧记录下来,日后忘了还能捡回来!
首先说为什么叫01背包,我理解为0指没有,1指有,所以01背包问题就是是否要取这一件物品。
假设有n件物品要装进最大能装w的背包里,然后每件物品对应一个价值value和重量weigth。
然后要求的是如何装才能使装的物品的价值最大。
思路如下:
1.如果给定了几件物品,那么背包的w越大,能够装的东西就越大,价值也就越大
2.如果背包的容量一定了,那么能够装下的物品的价值越大,总价值就会越大
3.所以这个总价值由两个因素决定,背包的容量和物品的价值。
4.然后可以把问题转化成背包的容量从0到最大的时候装或不装第i件物品
下面给出一个状态转移方程:
F[i][j]=max(F[i][j],F[i-1][j-weigth[i]]+value[i])
然后结合代码和上面的思路,我想你应该就明白了。
using namespace std;
int n,m,weigth,value,f[21][501];
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>value>>weigth;
for(int j=0;j<=m;j++)
{
if(j>=weigth) f[i][j]=max(f[i-1][j],f[i-1][j-weigth]+value);
else f[i][j]=f[i-1][j];
}
}
cout<<f[n][m];
}
用一维数组优化后:
using namespace std;
int n,m,weigth,value,f[501];
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>value>>weigth;
for(int j=m;j>=0;j--)
if(j>=weigth)
f[j]=max(f[j],f[j-weigth]+value);
}
cout<<f[m];
}