01背包问题

01背包问题是指给定 n 个物品的体积与价值,和背包体积 m,要求求背包能装下的最大价值。

 

状态表示:f [ i ][ j ] 表示在体积为 j 时从前 i 个物品中选出一定数量的物品的最大总价值。 

每个物品都有选或不选两种状态。

对于第 i 个物品:

选: f [ i - 1 ][ j - v[i] ] + w[ i ],也就是从前 i - 1件物品状态下找到一个预留了当前物品所需空间的状态,就可以把当期物品加进去,也就是加上价值。

不选:f [ i - 1][ j ],不选的话就是当前体积只从前 i - 1个物品中选了。

从前 i 个物品选择物品得到的最大价值为前 i - 1 个物品选出的最大值或 第 i 个物品的价值加上预留了第 i 个物品的体积后从 i - 1 个物品中选出的最大值。

状态转移方程 f [ i ][ j ] = max( f [ i - 1 ][ j ], f [ i - 1][ j - v[i] ] + w[i] ) 

当然不要忘记判断在当前体积下是否装得下。

装不下就承接上一个体积的最大值,因为是从小到大枚举体积的,当前体积装不下第 i 个物品,上一个体积也装不下,所以是一样的。

#include<iostream>

using namespace std;

const int N = 1010;

int f[N][N];

int v[N],w[N];

int n,m;

int main(){
        //物品数量和背包容积
	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 = 1; j <= m; j++)
			if(j < v[i])  //装不下
				f[i][j] = f[i][j-1];
			else      //装得下
				f[i][j] = max(f[i - 1][j], f[i-1][j-v[i]] + w[i]);


	cout << f[n][m];

	return 0;
}     

  

posted @ 2021-10-15 15:38  有手也不行  阅读(89)  评论(0编辑  收藏  举报