01背包之空间优化

前言:上篇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]);
		}
	}

是不是和二维思路差不多!其实挺简单的

结论:01背包既简单又实用,如果你看了我的文章很好理解。他就像高精度一样是个模板(不知道高精度的戳这

最好背下来哦!其实没必要背,理解理解就ok

posted @ 2020-08-04 10:49  riced  阅读(587)  评论(1编辑  收藏  举报