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); }