题解 | #购物单#

购物单

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

思路:
1、把价格和价值分别保存起来。price//价格 value//价值
2、用dp[i][j]表示前i个物品,价格为j时的最大价值。
3、得到状态转移方程 //k表示k种情况
/* 物品的选项
1、仅选主件
2、主件 + 附件1
3、主件 + 附件2
4、主件 + 附件1 + 附件2
*/ 所以k == 4

**dp[i][j] = MAX(dp[i-1][j], dp[i-1][j-price[i-1][k]] + value[i-1][k]);**

表示取每种情况的最大值

#include <stdio.h>

#define MAX(a, b) ((a>b)?(a):(b))

int main()
{
    int N = 0;    //钱
    int m = 0;    //物品数
    scanf("%d %d", &N, &m);
    /* 物品的选项
    1、仅选主件
    2、主件 + 附件1
    3、主件 + 附件2
    4、主件 + 附件1 + 附件2
    */
    int price[m][4];   //4种组合的全部价格
    int value[m][4];   //4种组合的满意度 = 价格 * 重要度(价值)
    memset(price, 0, m*4*sizeof(int));
    memset(value, 0, m*4*sizeof(int));

    int v = 0;    //价格
    int p = 0;    //重要度
    int q = 0;    //物品
    for(int i = 0; i < m; i++)
    {
        scanf("%d %d %d", &v, &p, &q);
        if(q == 0)    //表示主件
        {
            price[i][0] = v;
            value[i][0] = v * p;
        }
        else
        {
            if(price[q-1][1] == 0)
            {
                //附件1
                price[q-1][1] = v;
                value[q-1][1] = v * p;
            }
            else if(price[q-1][2] == 0)
            {
                //附件2
                price[q-1][2] = v;
                value[q-1][2] = v * p;

                //附件1 + 附件2,
                price[q-1][3] = price[q-1][1] + price[q-1][2];
                value[q-1][3] = value[q-1][1] + value[q-1][2];
            }
        }
    }

    //把主件的价格和满意度,添加到其余三个组合中
    for(int i = 0; i < m; i++)
    {
        for(int j = 1; j < 4; j++)
        {
            price[i][j] += price[i][0];
            value[i][j] += value[i][0];
        }
    }

    int dp[m+1][N+1];
    memset(dp, 0, (m+1)*(N+1)*sizeof(int));

    int max_value = 0;
    for(int i = 1; i < m+1; i++)    //表示m件物品
    {
        for(int j = 1; j < N+1; j++)    //表示N元钱
        {
            max_value = dp[i-1][j];
            for(int k = 0; k < 4; k++)
            {
                if(j - price[i-1][k] >= 0)
                {
                    //说明有足够的钱购买当前物品
                    max_value = MAX(max_value, dp[i-1][j-price[i-1][k]] + value[i-1][k]);
                }
            }
            //dp[i][j]表示前i个物品在钱数为j的情况下获取的最大满意度
            dp[i][j] = max_value;
        }
    }
    printf("%d\n", dp[m][N]);

    return 0;
}
全部评论

相关推荐

10-24 11:10
山西大学 Java
若梦难了:哥们,面试挂是很正常的。我大中厂终面挂,加起来快10次了,继续努力吧。
点赞 评论 收藏
分享
3 1 评论
分享
牛客网
牛客企业服务