冲刺华为、每天学五道 Day2

HJ16 购物单

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main(){
    int N, m; // N 奖金 m 物品个数
    cin >> N >> m;
    N /= 10; // 由于所有的价格都是10的整倍数,所以可以均除10以简化运算复杂度

    int price, priority, hasAttachments;
    // 使用一个(m+1)X6的数组存储数据,m+1是根据物品编号,0作废;6考虑可能有附件的最多的情况
    vector<vector<int>> data(m+1, vector<int>(6, 0));
    
    for(int i = 1; i <= m; i++){
        cin >> price >> priority >> hasAttachments;
        // 主件
        if(hasAttachments == 0){
            data[i][0] = price/10;
            data[i][1] = priority;
        }
        // 第一个附件
        else if(data[hasAttachments][2] == 0){
            data[hasAttachments][2] = price/10;
            data[hasAttachments][3] = priority;
        }
        // 第二个附件
        else {
            data[hasAttachments][4] = price/10;
            data[hasAttachments][5] = priority;
        }
    }

    vector<vector<int>> dp(m+1, vector<int>(N+1, 0));//背包容量记得加一
    for(int i = 1; i < m+1; i++){
        for(int j = 1; j < N+1; j++){ //j是总价值
            int pricePrime = data[i][0]; //先把每个物品及附属品加入到i中;因为是先买物品在卖附属品哦
            int priceAtta1 = data[i][2];
            int priceAtta2 = data[i][4];
            
            int priorPrime = data[i][1];
            int priorAtta1 = data[i][3];
            int priorAtta2 = data[i][5];

            dp[i][j] = j >= pricePrime ? max(dp[i-1][j - pricePrime] 
                                            + priorPrime * pricePrime, 
                                            dp[i-1][j]) : dp[i-1][j];//注意这边的大于等于号
            dp[i][j] = j >= (pricePrime + priceAtta1) ? max(dp[i-1][j - pricePrime - priceAtta1]
                                                        + priorPrime * pricePrime 
                                                        + priorAtta1 * priceAtta1, 
                                                        dp[i][j]) : dp[i][j];
            dp[i][j] = j >= (pricePrime + priceAtta2) ? max(dp[i-1][j - pricePrime - priceAtta2]
                                                        + priorPrime * pricePrime 
                                                        + priorAtta2 * priceAtta2, 
                                                        dp[i][j]) : dp[i][j];//可以不买attach1,而直接购买attach2,别忘了。
            dp[i][j] = j >= (pricePrime + priceAtta1 + priceAtta2) ? 
                                                        max(dp[i-1][j - pricePrime - priceAtta1 - priceAtta2]
                                                        + priorPrime * pricePrime 
                                                        + priorAtta1 * priceAtta1
                                                        + priorAtta2 * priceAtta2, 
                                                        dp[i][j]) : dp[i][j];
        }
    }
    cout << dp[m][N] * 10 <<endl;
    return 0;
}

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

int main() {
        int N,m;
        cin>>N>>m;

        int price,priority,hasAttachments;
        vector<vector<int>> data(m+1,vector<int>(6,0));

        for(int i=1; i<=m;i++){
            cin>>price>>priority>>hasAttachments;
            if(hasAttachments == 0){
                data[i][0]=price;
                data[i][1]=priority;
            }
            else if (data[hasAttachments][2]==0){
                data[hasAttachments][2]=price;
                data[hasAttachments][3]=priority;
            }
            else {
                data[hasAttachments][4]=price;
                data[hasAttachments][5]=priority;
            }
        }  
        vector<int> dp(N+1,0);
        for(int i=1;i<=m;i++){
            int PricePrime=data[i][0];
            int PriceAtta1=data[i][2];
            int PriceAtta2=data[i][4];

            int PriorityPrime=data[i][1];
            int PriorityAtta1=data[i][3];
            int PriorityAtta2=data[i][5];

            for(int j=N;j>=PricePrime;j--){
                dp[j]=max(dp[j],dp[j-PricePrime]+PricePrime*PriorityPrime);
                dp[j]=j>= (PricePrime+PriceAtta1)?max(dp[j],dp[j-PricePrime-PriceAtta1]+PricePrime*PriorityPrime+PriceAtta1*PriorityAtta1):dp[j];

                dp[j]=j>= (PricePrime+PriceAtta2)?max(dp[j],dp[j-PricePrime-PriceAtta2]+PricePrime*PriorityPrime+PriceAtta2*PriorityAtta2):dp[j];

                dp[j]=j>=(PricePrime+PriceAtta1+PriceAtta2)?max(dp[j],dp[j-PricePrime-PriceAtta1-PriceAtta2]+PricePrime*PriorityPrime+PriceAtta1*PriorityAtta1+PriceAtta2*PriorityAtta2):dp[j];
            }

        }
    
        

  cout<<dp[N]<<endl;
    
}
// 64 位输出请用 printf("%lld")
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值