01背包-完全背包-多重背包问题解决方法

1. 0-1 背包

0-1背包问题描述:有N件物品和一个容量为V的背包。第i件物品的重量是w[i],价值是v[i]。求解将哪些物品装入背包可使这些物品的重量总和不超过背包容量,且价值总和最大。

这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放。
用子问题定义状态:即f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值。则其状态转移方程便是:
f[i][v]=max{ f[i-1][v], f[i-1][v-w[i]]+v[i] }
可以压缩空间,f[v]=max{f[v],f[v-w[i]]+v[i]} 这行代码是核心

解决该类问题的一般代码:

for(int i=0;i<N;i++)	//选取前 i 件物品
	for(int j=V;j>=w[i];j--)	//从最大容量开始逆序,最小不能小于第 i 件物品的重量,否则 f[v-w[i]] 将无意义
		f[v] = max(f[v],f[v-w[i]]+v[i]);	//决定是否要将第 i 件物品放入背包中,前者为不放,后者为放

2.完全背包

完全背包问题描述:有N种物品和一个容量为V的背包,每种物品都有无限件可用。第i种物品的重量是w[i],价值是v[i]。将哪些物品装入背包可使这些物品的体积总和不超过背包容量,且价值总和最大。

解决该类问题的一般代码:

for(int i=0;i<N;i++)	//选取前 i 件物品
	for(int j=0;j<=V;j++)	
		f[v] = max(f[v],f[v-w[i]]+v[i]);

3.多重背包

多重背包问题描述:有N种物品和一个容量为V的背包。第i种物品最多有n[i]件可用,第i件物品重量是w[i],价值是v[i]。求解将哪些物品装入背包可使这些物品的体积总和不超过背包容量,且价值总和最大。

解决该类问题的一般代码:

for(int i=0;i<N;i++)
        for(int j=V;j>=w[i];j--)
            for(int k=1;k<=n[i]&&k*w[i]<=j;k++)
                f[j] = max(f[j],f[j-k*w[i]]+v[i]*k);

猜你喜欢

转载自blog.csdn.net/Mr_Lewis/article/details/88051036