C++ 关于01背包(简单动规)问题的两种解法

/* 注:本题使用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[n][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); }

你可能感兴趣的:(蓝桥集训)