01背包之二维数组

Dev.C++动态规划01背包:背包是一种特殊动态规划,而01背包就是只有选与不选的状态,这是最简单的理解。
老规矩,先贴代码:


#include<bits/stdc++.h>
using namespace std;
int bag,n,v[101],w[101],dp[1001][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=1;j<=bag;j++)
		{
			if(j>v[i])dp[i][j]=max(dp[i-1][j],dp[i-1][j-v[i]]+w[i]);
			else dp[i][j]=dp[i-1][j];
		}
	}
	cout<<dp[n][bag]<<endl;
	return 0;
}

变量解释:bag:背包总容量

  • n:物品的数量
  • v[i]:第i件物品的体积
  • w[i]:第i件物品的价值
  • dp[i][j]:第i件物品和在它以前选的j重量的情况下的最佳选择方案的总价值
    解释代码:
//重点代码
      for(int i=1;i<=n;i++)
      {
            for(int j=1;j<=bag;j++)
            {
                  if(j>v[i])dp[i][j]=max(dp[i-1][j],dp[i-1][j-v[i]]+w[i]);
                  else dp[i][j]=dp[i-1][j];
            }
      }

第一层循环:枚举每一件物品
第二层循环:枚举每一种重量
条件语句:对是否放的下第i件物品的判断
状态转移方程:

dp[i-1][j]:不选这件物品的情况。为什么是这样呢?j不动,是指没有放入任何东西。这就是不选的情况。

dp[i-1][j-v[i]]+w[i]:选择这件物品的情况。为什么呢?j-v[i],是目前背包内剩余空间减去这件物品的体积,加w[i],是指加上这件物品的价值。

在这两种情况中取max,就是目前的最佳情况了。这就是二维数组动态规划01背包的做法。

总结:01背包很好识别,其实也可以背模板。但是如果数据卡常,空间就可能会爆,于是

我们启用了一维数组动态规划01背包。

posted @ 2020-08-04 10:40  riced  阅读(497)  评论(0编辑  收藏  举报