题解 | #购物单#

购物单

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;
}
全部评论

相关推荐

面试官全程关摄像头1.自我介绍一下2.React和Vue哪个更熟悉一点3.你在之前那段实习经历中有没有什么技术性的突破(我只是实习了44天工作28天,我把我能说的都说了)4.你封装的哪个表单组件支不支持动态传值5.自己在实习阶段Vue3项目封装过hook吗6.hook有什么作用7.Vue2和Vue3的响应式区别(我说一个是proxy是拦截所有的底层操作,Object.defineProperty本身就是一个底层操作,有些东西拦截不了,比如数组的一些操作还有等等,面试官就说实在要拦截能不能拦截????我心想肯定不行呀,他的底层机制就不允许吧)8.pinia和vuex的区别(这个回答不出来是我太久没用了)9.pinia和zustand的区别,怎么选(直接给我干懵了)(我说react能用pinia吗&nbsp;&nbsp;他说要用的话也可以)10.渲染一万条数据,怎么解决页面卡顿问题(我说分页、监听滚轮动态加载,纯数据展示好像还可以用canvas画)(估计是没说虚拟表单,感觉不满意)11.type和interface的区别12.ts的泛型有哪些作用(我就说了一个结构相同但是类型不同的时候可以用,比如请求响应的接口,每次的data不同,这里能用一个泛型,他问我还有什么)13.你项目用的是React,如果让你再写一遍你会选择什么14.pnpm、npm、yarn的区别15.dependencies和devdependencies的区别总而言之太久没面试了,上一段实习的面试js问了很多。结果这次js一点没问,网络方面也没考,表现得很一般,但是知道自己的问题了&nbsp;&nbsp;好好准备,等待明天的影石360和周四的腾讯了&nbsp;&nbsp;加油!!!
解zj:大三的第一段面试居然是这样的结局
查看15道真题和解析
点赞 评论 收藏
分享
评论
4
1
分享

创作者周榜

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