题解 | 购物单

购物单

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

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

void getGoods(int count, vector< vector<int>>& goods) {
    for (int i = 1; i < count; i++) {   // 接收数据
        // goods[i][0] 为 价格 goods[i][1] 为 重要度 goods[i][2] 为 主件编号
        cin >> goods[i][0] >> goods[i][1] >> goods[i][2];
        goods[i][0] /= 10;
    }
    for (int i = 1; i < count; i++) {
        if (goods[i][2] != 0) { // 如果为附件 goods[i][3] 为编号为i的商品第一个附件
            if (goods[goods[i][2]][3] == 0) {
                // goods[i][3] 为编号为i的商品第一个附件
                goods[goods[i][2]][3] = i;
            } else if (goods[goods[i][2]][4] == 0) {
                // goods[i][4] 为编号为i的商品第二个附件
                goods[goods[i][2]][4] = i;
            }
        }
    }
}
/*
i 为 物品的编号 j 为 预算 dp[i][j] 为j 预算下 买 前i 件物品的 最佳满意度
可以将问题抽象为 dp[i][j] = max{dp[i-1][j], judge(i, j)}
其中 judge(i, j)表示 dp[i][j]在以下四种情况的满意度
1、只买 i 本身, 无附件
2、买 i本身 加 i的第一个附件
3、买i本身 加 i 的第二个附件
4、买i本身加 i 的两个附件
*/

int max(int a, int b, int c, int d){
    return max({a, b, c, d});
}

void maxSatisfaction(int money, int count, vector< vector<int>>& goods) {
    vector < vector<int>> dp(count + 1, vector(money + 1, 0));
    for (int i = 0; i < count + 1; i++) {
        int price0, price1, price2, price3;
        int value0, value1, value2, value3;
        price0 = price1 = price2 = price3 = 0;
        value0 = value1 = value2 = value3 = 0;

        // 只考虑主件
        price0 = goods[i][0];
        value0 = goods[i][1] * goods[i][0];
        // 主件+附件1
        price1 = goods[goods[i][3]][0] + price0;
        value1 = goods[goods[i][3]][1] * goods[goods[i][3]][0] + value0;
        // 主件+附件2
        price2 = goods[goods[i][4]][0] + price0;
        value2 = goods[goods[i][4]][1] * goods[goods[i][4]][0] + value0;
        // 主件+附件1+附件2
        price3 = price1 + price2 - price0;
        value3 = value1 + value2 - value0;

        // 填充dp 数组
        for (int j = 1; j < money + 1; j++) {
            if (goods[i][2] != 0 || j < price0) {
                dp[i][j] = dp[i - 1][j];
            } else {
                int a0, a1, a2, a3;
                a0 = a1 = a2 = a3 = 0;
                // 只买主件
                if (j >= price0 && price0 != 0) {
                    a0 = max(dp[i - 1][j], dp[i - 1][j - price0] + value0);
                }
                // 主件 + 附件1
                if (j >= price1 && price1 != 0) {
                    a1 = max(dp[i - 1][j], dp[i - 1][j - price1] + value1);
                }
                // 主件 + 附件2
                if (j >= price2 && price2 != 0) {
                    a2 = max(dp[i - 1][j], dp[i - 1][j - price2] + value2);
                }
                // 主件 + 附件1 + 附件2
                if (j >= price3 && price3 != 0) {
                    a3 = max(dp[i - 1][j], dp[i - 1][j - price3] + value3);
                }
                dp[i][j] = max(a0, a1, a2, a3);
            }  
        }
    }

    cout << dp[count][money] * 10 << endl;
}

int main() {

    int money, count;
    cin  >> money >> count;
    money /= 10;
    vector< vector<int>> goods(count +1, vector<int>(5, 0));   // goods每行有五列
    getGoods(count +1 , goods);
    maxSatisfaction(money, count, goods);

    return 0;

}
// 64 位输出请用 printf("%lld")

全部评论

相关推荐

01-15 13:45
门头沟学院 Java
牛客92772631...:boss招聘挂岗位是要花钱的,花了钱不挂白不挂,别那么焦虑,但是也要做好跳槽的准备
找实习记录
点赞 评论 收藏
分享
评论
点赞
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务