背包粗讲

1.01背包:有n种物品与承重为m的背包。每种物品只有一件,每个物品都有对应的重量weight[i]与价值value[i],求解如何装包使得价值最大。

板子: (这里用到了滚动数组,空间优化)

for(int i = 1;i <= n;i ++)  //n种物品 
{
	for(int j = bag;j >= w[i];j --)  //因为你要用到上一状态的值  所有必须从后向前遍历 
	{
		dp[j] = max(dp[j], dp[j - w[i]] + v[i]);
	}
}

2.完全背包:有n种物品与承重为m的背包。每种物品有无限多件,每个物品都有对应的重量weight[i]与价值value[i],求解如何装包使得价值最大。

板子:此时与01的区别在于 数量无限  第二循环正着遍历的意义在于每次取不同个数的物品找最优

for(int i = 1;i <= n;i ++)  //n种物品 
{
	for(int j = w[i];j <= bag;j ++)
	dp[j] = max(dp[j], dp[j - w[i]] + v[i]); 
}

3.多重背包:有n种物品与承重为m的背包。每种物品有有限件num[i],每个物品都有对应的重量weight[i]与价值value[i],求解如何装包使得价值最大。

板子:和01背包类似  多了一层遍历物品个数的循环

当然 数据 时间要求严格时 需要用二进制枚举

for(int i = 1;i <= n;i ++)  //n种物品 
{
	for(int j = 0;j < num[i];j ++)  //对每种物品的个数开始遍历   (这是在数据很小的情况下 数据大的时候用二进制枚举) 
	{
		for(int k = bag;k >= w[i];k --)   // 写法如 01背包 
		{
			dp[k] = max(dp[k], dp[k - w[i]] + v[i]);
		}
	}
}

下面是多重背包的一道应用题

hdu2844 点击打开链接

当 价值与个数的乘积大于 容量m时  这时 我们可以把它当着 用不完的数量  即看作 完全背包   

相反  小于m时  则当作 01背包处理   然后 利用二进制枚举  

#include<bits/stdc++.h>
using namespace std;
int m, n;
int v[105],num[105];
int dp[100005];
int main()
{
    while(cin >> n >> m && n && m)
    {
    	fill(dp,dp + 100005, -99999999);
    	dp[0] = 1;  //面值为0的时候只要一种选择  即 不掏钱 
    	for(int i = 1;i <= n;i ++)
    	{
    		cin >> v[i];
		}
		for(int i = 1;i <= n;i ++)
    	{
    		cin >> num[i];
		}
		for(int i = 1;i <= n;i ++)
		{
			//按完全背包算 
			if(num[i] * v[i] >= m)
			{
				for(int j = v[i];j <= m;j ++)
				dp[j] = max(dp[j], dp[j - v[i]] + v[i]);
			}
			else
			{
				for(int j = 1;j <= num[i];j = j*2)
				{
					for(int k = m;k >= v[i] * j;k --)
					{
						dp[k] = max(dp[k], dp[k - v[i] * j] + v[i] * j);
					}
					num[i] -= j;
				}
				
				if(num[i] > 0)
				{
					for(int j = m;j >= v[i] * num[i];j --)
					dp[j] = max(dp[j], dp[j - v[i] * num[i]] + v[i] * num[i]);
				}
			}
		}
		
		int cnt = 0;
		for(int i = 1;i <= m;i ++)
		{
			if(dp[i] > 0)   //i表示面值  如果说面值为i时的值不为0  则 说明此时有组成i的解 
			cnt ++;
		}
		
		cout << cnt << endl; 
		
	}
    return 0;
}

猜你喜欢

转载自blog.csdn.net/soul_97/article/details/80273785