DP查缺补漏之多重背包优化原理

DP查缺补漏之多重背包优化原理

普通思路

  • 类似完全背包

  • for (int i = 1; i <= n; i++)
    	{
    		for (int j = 1; j <= W; j++)
    		{
    			for (int k = 0; k * w[i] <= j && k <= m[i]; k++)
    			{
    				F[i][j] = max(F[i][j], F[i - 1][j - k * w[i]] + k * v[i]);
    			}
    		}
    	}
    
  • 这里注意\(j\)一定要从\(1\)开始枚举,如果 从\(w[i]\)开始则无法更新小于\(w[i]\)时的\(F[i-1][j]\)

    • 而为滚动数组时,若小于\(j <= w[i]\)能自动使用上一次的\(F[j]\),所以\(j\)才能从\(w[i]\)开始枚举

二进制拆分优化

原理

任何数都能用二进制表示,任何正整数都能由若干个不同的\(2^n\)相加得到。

做法

直接把多重背包每一个物品的总数量用二进制预处理成几个大物品。

然后直接用物品跑01背包即可

代码

for (int i = 1; i <= n; i++)
	{
		cin >> a >> b >> c;
		int bin = 1;
		while(bin <= c)
		{
			v[++cnt] = bin * a;
			w[cnt] = bin * b;
			c -= bin;
			bin <<= 1;
		}
		if (c)
		{
			v[++cnt] = c * a;
			w[cnt] = c * b;
		}
	}
posted @ 2023-11-01 22:27  加固文明幻景  阅读(4)  评论(0编辑  收藏  举报