01背包详解(二维到一维)

01背包详解(二维到一维)_第1张图片

 

有 N件物品和一个容量为 V 的背包,每件物品有各自的价值且只能被选择一次,要求在有限的背包容量下,装入的物品总价值最大。「0-1 背包」是较为简单的动态规划问题,也是其余背包问题的基础。

动态规划是不断决策求最优解的过程,「0-1 背包」即是不断对第 i个物品的做出决策,「0-1」正好代表不选与选两种决定。

二维代码实现

#include
using namespace std;
const int N=1e3+10;
int v[N],w[N],f[N][N];

int main(){
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++)cin>>v[i]>>w[i];
	
	
	for(int i=1;i<=n;i++){
		for(int j=0;j<=m;j++){
			f[i][j]=f[i-1][j];  //当前背包容量j=v[i])   //如果j>v[i],进行选择放与不放第i个物品
			f[i][j]=max(f[i][j],f[i-1][j-v[i]]+w[i]);
		}
	}
	cout<

一维代码 

#include
using namespace std;
const int N=1e3+10;
int v[N],w[N],f[N];

int main(){
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++)cin>>v[i]>>w[i];
	
	
	for(int i=1;i<=n;i++){
		for(int j=m;j>=a[i];j--){
			f[j]=max(f[j],f[j-v[i]]+w[i]);  //背包容量是从大到小的因此j一定大于a[i] 
		}
	}
	cout<
for(int j=m;j>=a[i];j--){
			f[j]=max(f[j],f[j-v[i]]+w[i]);  //背包容量是从大到小的因此j一定大于a[i] 
		}

一定要从m开始进行逆序计算,在二维情况下f[i][j]是由i-1的状态得来的,f[i][j]与f[i-1][j]是完全独立的,但是当我们优化到一维后我们可能会在该使用i-1的位置用到i,例如,一维状态第i轮对体积为 3的物品进行决策,则f[7]f[4]更新而来,这里的f[4]正确应该是f[i - 1][4],但从小到大枚举j这里的f[4]在第i轮计算却变成了f[i][4]。当逆序枚举背包容量j时,我们求f[7]同样由f[4]更新,但由于是逆序,这里的f[4]还没有在第i轮计算,所以此时实际计算的f[4]仍然是f[i - 1][4]

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