题解 | 购物单

购物单

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

#include <iostream>
#include <vector>
using namespace std;

int main() {
    int n, m;
    cin >> n >>m;
    n /= 10;
    vector<vector<int>> prices(m+1, vector<int>(3, 0)); // 第0列是主物品自身的price,第1、2列是附属物品的price(如有)
    vector<vector<int>> satisfy(m+1, vector<int>(3, 0));
    for(int i = 1; i<=m; i++) {
        int a, b, c;
        cin >> a >>b>>c;
        a/=10; b = b*a;
        if (c == 0) {
            // 主物品
            prices[i][0] = a;
            satisfy[i][0] = b;
        } else {
            // 附属物品,我要把它放到对应的主物品里面
            if (prices[c][1] == 0) {
                prices[c][1] = a;
                satisfy[c][1] = b;
            } else {
                prices[c][2] = a;
                satisfy[c][2] = b;
            }
        }
    }

    // cout << "hello";
    // 设置好了所有主物品的信息

/*
    // 求解前i个主物品,在容量为j的情况下,能获得的最大满意度
    // 根据第i个物品是否取用,分为两种情况:
         1. 不取用,则问题变成前i-1个主物品在容量为j的情况下取得的最大满意度
         2. 取用:
                此时如果不考虑附属物品的问题,那就是纯粹的01背包了;前面i-1个主物品在j-第i个物品的容量下的最大满意度,再加上第i个物品所取得的满意度。
                进一步考虑附属物品的问题:其实就是取用的场景可以进一步划分为4种情况:
                    1.不取附属物品。
                    2.只取附属物品1
                    3.只取附属物品2
                    4.同时取附属物品1和2
*/

// 大的框架并没有跳出01背包问题:最终就是求前m个主物品,在容量为n下能取得的最大满意度。

    vector<vector<int>> dp(m+1, vector<int>(n+1, 0));
    for(int i = 1; i<=m; i++) {
        for(int j = 1; j<=n; j++) {
            // 求dp[i][j]的值
            int p = prices[i][0], s = satisfy[i][0];           
            int sub1_p = prices[i][1], sub1_s = satisfy[i][1];
            int sub2_p = prices[i][2], sub2_s = satisfy[i][2];

            // 不取
            dp[i][j] = dp[i-1][j];

            // 取
            dp[i][j] = j >= p ? max(dp[i][j], dp[i-1][j-p]+s) : dp[i][j];
            dp[i][j] = j >= (p+sub1_p) ? max(dp[i][j], dp[i-1][j-p-sub1_p] + s + sub1_s) : dp[i][j];
            dp[i][j] = j >= (p+sub2_p) ? max(dp[i][j], dp[i-1][j-p-sub2_p] + s + sub2_s) : dp[i][j];
            dp[i][j] = j >= (p+sub1_p+sub2_p) ? max(dp[i][j], dp[i-1][j-p-sub1_p-sub2_p]+s+sub1_s+sub2_s) : dp[i][j];
            // cout << dp[i][j] << endl;
        }
    }
    cout << dp[m][n]*10;
}
// 64 位输出请用 printf("%lld")

全部评论

相关推荐

04-03 22:39
重庆大学 Java
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务