题解 | #购物单#超清楚的分析

购物单

http://www.nowcoder.com/practice/f9c6f980eeec43ef85be20755ddbeaf4

我本身不是科班出身,通过查阅资料,理解了最简单的01背包问题,下面谈一谈我的理解

背包问题主要就是这个等式 dp[n][c]=max{dp[n-1][c-cost[i]]+value[i],dp[n-1][c]}

他是一个状态转移方程,n指的是背包问题里放物品的个数,该物品有重量(代价)和价钱(价值)两个属性,c指的是背包能背的重量,而dp[n][c]指的是在前n个物品中装到承载重量为c的背包中,使得背包里的物品总价值最大。我们可以仔细思考一下,发现这个最大值的状态跟他把前n-1个物品装到承载为c的背包中似乎有关系。这个等式我认为应该这样理解,max里的第一项代表背包里装了第i个物品,第二项代表没装。意思就是前n项能得出来的最大值,要么装了i物品得到的(第一项我们把i物品扣掉得到的式子dp[n-1][c-cost[i]就是前n-1个物品在该承重下的最大值,然后再加上value[i]得到可能的现有状态的最大值),要么没装就可以得到,那其实就是只有n-1项也可以得到n项状态的最大值。

首先要明白背包问题,背包是作为一种条件限制,可以理解为背包就是“某种有限的东西”,举个例子,比如这道题“有限的东西”就是指的“他的年终奖”,而背包问题里物品的“重量”,抽象的说就是某种“代价”,这道题的“代价”就是每件物品的价钱,而背包问题里的物品的“价值”,可以抽象成”某种有用的属性“,这道题的“某种有用的属性”就是题干说的重要程度

下面程序的cost就是指的代价,value指的价值,而题目中的主件与附件,我们可以把它想象成捆绑在一起,也就是无论它是哪种情况(1、主件;2、主件,附件1;3、主件,附件2;4、主件,附件1,附件2)我们都先把它想象成一个整体。

#include <string>
#include <set>
#include <vector>

using namespace std;

int main() {
    unsigned N, m;
    unsigned cost,value , inherit;
    cin >> N >> m;
    //N/=10;
    vector<vector<unsigned>> dp(m + 1, vector<unsigned>(N + 1, 0));
    vector<vector<unsigned>> costarray(m + 1, vector<unsigned>(4, 0));
    vector<vector<unsigned>> valuearray(m + 1, vector<unsigned>(4,0));
    for (int i = 1; i <= m; i++) {
        cin >> cost >> value >> inherit;
        //cost /= 10;

        if (inherit == 0) {
            valuearray[i][1] = value;
            costarray[i][1] = cost;
        }
        else if (inherit != 0 && costarray[inherit][2] == 0) {

            valuearray[inherit][2] = value;
            costarray[inherit][2] = cost;
        }
        else {
            valuearray[inherit][3] = value;
            costarray[inherit][3] = cost;
        }
    }


    for (int i = 1; i <= m; i++) {
        for (int j = 1; j <= N; j++) {
            unsigned valueprimer = valuearray[i][1];
            unsigned costprimer = costarray[i][1];
            unsigned valueherit1 = valuearray[i][2];
            unsigned costherit1 = costarray[i][2];
            unsigned valueherit2 = valuearray[i][3];
            unsigned costherit2 = costarray[i][3];

            unsigned x1 = costprimer;
            unsigned x2 = costprimer+costherit1;
            unsigned x3 = costprimer+costherit2;
            unsigned x4 = costprimer+costherit1+costherit2;

            unsigned m1 = valueprimer * costprimer;
            unsigned m2 = valueprimer * costprimer + valueherit1 * costherit1;
            unsigned m3 = valueprimer * costprimer + valueherit2 * costherit2;
            unsigned m4 = valueprimer * costprimer + valueherit1 * costherit1 + valueherit2 * costherit2;

            unsigned prev1 = dp[i - 1][j];
          

            dp[i][j] = j >= x1 ? max(prev1, dp[i - 1][j - x1] + m1) : prev1;
            dp[i][j] = j >= x2 ? max(dp[i][j], dp[i - 1][j - x2] + m2) : dp[i][j];
            dp[i][j] = j >= x3 ? max(dp[i][j], dp[i - 1][j - x3] + m3) : dp[i][j];
            dp[i][j] = j >= x4 ? max(dp[i][j], dp[i - 1][j - x4] + m4) : dp[i][j];
        }


    }
    cout << dp[m][N] << endl;
    





}

全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务