[题解] 购物单-华为机试

购物单

解题思路

较为抽象的01背包问题,

请添加图片描述

# include <iostream>
# include <vector>

using namespace std;

int main()
{
    int N, m;
    cin >> N >> m;
    int value, priority, q;
    int i, j;
    vector<vector<int>> data(m+1, vector<int>(6, 0));

    for(i = 1; i <= m; i++)
    {
        cin >> value >> priority >> q;
        // 是主件
        if(q == 0)
        {
            data[i][0] = value;
            data[i][1] = priority;
        }
        // 第一个附件
        else if(data[q][2] == 0)
        {
            data[q][2] = value;
            data[q][3] = priority;
        }
        else 
        {
            data[q][4] = value;
            data[q][5] = priority;
        }
    }

    vector<vector<int>> dp(m+1, vector<int>(N+1, 0));
    for(i = 1; i <= m; i++)
    {
        for(j = 1; j <= N; j++)
        {
            int value1 = data[i][0]; // 主件
            int value2 = data[i][2]; // 附件1
            int value3 = data[i][4]; // 附件2
        
            int prior1 = data[i][1];
            int prior2 = data[i][3];
            int prior3 = data[i][5];

            if(j >= value1)
            {
                dp[i][j] = max(dp[i-1][j], dp[i-1][j-value1] + value1 * prior1);
            }
            else 
            {
                dp[i][j] = dp[i-1][j];
            }

            if(j >= value1 + value2)
            {
                dp[i][j] = max(dp[i][j], 
                            dp[i-1][j - value1 - value2] + value1 * prior1 + value2 * prior2);
            }

            if(j >= value1 + value3)
            {
                dp[i][j] = max(dp[i][j], 
                            dp[i-1][j - value1 - value3] + value1 * prior1 + value3 * prior3);
            }

            if(j >= value1 + value2 + value3)
            {
                dp[i][j] = max(dp[i][j],
                            dp[i-1][j-value1-value2-value3] + value1 * prior1 + value2 * prior2 + value3 * prior3);
            }
        }
    }
    cout << dp[m][N] << endl;

    return 0;
}

参考

华为机试-牛客网
购物单题解

  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值