前言:上篇suibi写到了01背包的二维数组做法(不知道的戳这),可是空间太大了,如果出题人有意,那你就
BOOM
怎么办呢?那咱们就用一维数组来存吧。
代码代码:
#include<bits/stdc++.h>
using namespace std;
int bag,n,v[101],w[101],dp[1001];
int main()
{
scanf("%d%d",&bag,&n);
for(int i=1;i<=n;i++)scanf("%d%d",&v[i],&w[i]);
for(int i=1;i<=n;i++)
{
for(int j=bag;j>=v[i];j--)
{
dp[j]=max(dp[j],dp[j-v[i]]+w[i]);
}
}
cout<<dp[bag]<<endl;
return 0;
}
变量同上。
同样枚举每一种物品,重量从后往前枚举。
看图:
这样从后往前枚,就可以避免重复了,因为01背包每种物品只能选一次。例如从12没枚2,发现0+2=2!于是二就有了方案。
从12枚举到5,发现2满了,而2+3=5!于是5也有了方案。再枚下去,发现0+3=3!于是,三也有了方案。以此类推,我们发现
不需要枚举数组第一个下标即物品的编号!于是就有了
for(int i=1;i<=n;i++)
{
for(int j=bag;j>=v[i];j--)
{
dp[j]=max(dp[j],dp[j-v[i]]+w[i]);
}
}
是不是和二维思路差不多!其实挺简单的