您的位置:首页 > 其它

Exercise(4):01背包(简单动规)问题的两种解法

2016-03-13 19:44 381 查看
/*
注:本题使用VC++6.0 版本 语言:C++

有N件物品和一个容量为V的背包。第i件物品的重量是w[i],价值是v[i]。
求解将哪些物品装入背包可使价值总和最大。
输入:
第一行两个整数分别是N件物品与背包容量V
接下来分别是N行,每行两个数分别是当前物品的重量w与价值v;

输出:
在不超过背包容量的前提下输出最大的价值总和。

测试数据:
5 10
2 6
2 3
6 5
5 4
4 6

15

*/
// 建议可以用excel表格建表并按照代码一步一步分析

-------------------------二维-------------------------
#include <iostream>
using namespace std;
int max(int,int);

int main()
{
// n为物品件数 m为背包容量 i,j为循环变量
int n,m,i,j;
cin>>n>>m;

// w[100]为各物品重量 v[100]为各物品价值
int w[100],v[100];
// 此处空出第1行,第1列初始化为0
for( i = 1; i <= n; ++i )
cin>>w[i]>>v[i];

// d[100][100]为最大价值表 此处初始化第1行,第1列为0
int d[100][100];
for( i = 0; i <= n ; ++i )
d[i][0] = 0;
for( i = 0; i <= m; ++i )
d[0][i] = 0;

// 从d[1][1]开始遍历
for( i = 1; i <= n; ++i )
for( j = 1; j <= m; ++j )
// 当物品重量大于对应背包容量时,价值为0
if(j < w[i]) d[i][j] = 0;
else
// 状态转移方程:
/*
对于当前物品w[i]有两种状态:装和不装
①不装:若不装入,则以上一级的值 d[i-1][j]
为d[i][j]的值。
②装:若装入,则需要计算装入该物品后背包剩余
的容量j-w[i]在上一级的最大价值
d[i-1][j-w[i]] .
最后比较装与不装 哪种状态价值更大,选择最大。
*/
d[i][j] = max(d[i-1][j-w[i]]+v[i],d[i-1][j]);

// 表格完成后,有效数据域内右下角的值为最大价值。
cout<<d
[m]<<endl;
return 0;
}

// 一般来说在标准C++库内已经含有max函数,无需自行定义。
// 但由于编译环境版本低的问题 需要自行定义
int max(int a, int b)
{ return (a>b?a:b); }

// 计算价值表时不一定要从上到下,也可以从下到上。

-------------------------一维-------------------------
// 可参考二维解法思考一下一维解法,改变处已标出
#include <iostream>
using namespace std;
int max(int,int);

int main()
{
int n,m,i,j;
cin>>n>>m;

int w[100],v[100];
w[0] = 0; v[0] = 0;  //此
for( i = 1; i <= n; ++i )
cin>>w[i]>>v[i];

int d[100];  //此
for( i = 0; i <= m; ++i )
d[i] = 0;  //此

for( i = 1; i <= n; ++i ) //此
for( j = m; j >= w[i]; --j )  //此
d[j] = max(d[j-w[i]]+v[i],d[j]);  //此

cout<<d[m]<<endl;  //此
return 0;
}

int max(int a, int b)
{ return (a>b?a:b); }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  蓝桥