完全背包算法

上次,我们把完全背包转换成了0-1背包。

由于至少放入一个,考虑最后一个放入的物品,其占用w的空间,价值是v。

由于物品有无限多个,放入一个以后还是有无限多个,但是背包大小减少了w。

问题转换为从前i个物品种选择一些物品放入j-w[i]的背包中可以获得的最大价值

由此推出状态转移方程:dp[i][j]=max(dp[i-1][j],dp[i-1][j-k*w[i]]+k*v[i])

那么能在空间上再优化一下吗?当然可以!

我们用滚动数组,优化状态转移方程

方程优化成这样:dp[j]=max(dp[j],dp[j-w[i]]+v[i])

虽然它的状态转移方程和0-1背包的一样,但是它不用倒着循环,正着循环即可。

#include 
using namespace std;
//对于物品i,你可以把它打入冷宫(不选)或者让它入宫(选) 
//不过啊,这是无限背包,所以可以无限放 
//也就是说,你放完一个,还有无限个,但是呢背包的大小减少了w[i]
//因此问题转化为从前i个物品中选一些放入大小为j-w[i]的背包中可获得的最大价值
int w[maxn],v[maxn],dp[maxm];
int main(){
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++)
		cin>>w[i]>>v[i];
	for(int i=1;i<=n;i++){
		for(int j=w[i];j<=m;j++)//这个正着循环即可
			dp[j]=max(dp[j],dp[j-w[i]]+v[i]); 
	}
	cout<

好了,完全背包的讲解暂时告一段落。

这时候肯定有人会问了:不是还能转多重背包吗?

没错,我等到下期多重背包讲完了,再来填这个坑。

你可能感兴趣的:(动态规划,动态规划,算法)