题解 | #购物单#

购物单

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

#include <stdio.h>
#include <stdlib.h>
#define N 60                               // 最多 60 件物品
#define M 32000                            // 最多预算数 
#define MAX(a, b) ((a) > (b)) ? (a) : (b)  // 宏函数参数最好加括号避免出错 

int main(void)
{
	int money;               // 预算
	int n;                   // 货物数量
	int v;                   // 单个物品价格
	int p;                   // 单个物品满意度
	int q;                   // 物品所属编号
	static int price[N][4];  // 存储可能的四种组合的商品的价格,静态变量自动初始化为 0 
	static int weight[N][4]; // 存储可能出现的四种组合的满意度 
	int merge_price[N][4];   // 存储合并后的价格
	int merge_weight[N][4];  // 存储合并后的满意度 
	int count = 0;           // 记录组合商品数量 
	static int dp[N][M];     // M 数量的金钱购买 N 个物品最多获取满意度
	int max = 0;             // 存储最大满意度 
	int i, j, k; 
		
	while (scanf("%d%d", &money, &n) == 2)
	{
		/* 数据处理开始,录入并合并数据*/ 
		for (i = 0; i < n; i++)
		{
			scanf("%d%d%d", &v, &p, &q);
			if (0 == q)
			{
				price[i][0] = v;
				weight[i][0] = v * p;
			}
			else if (0 == price[q - 1][1]) // 表明是数组编号为 q - 1第 1 件附件 
			{
				price[q - 1][1] = v;
				weight[q - 1][1] = v * p; 
			}
			else                           // 表明是数组编号为 q - 1的物品的第 2 件附件
			{
				price[q - 1][2] = v;
				weight[q - 1][2] = v * p;  
				price[q - 1][3] = price[q - 1][1] + v;
				weight[q - 1][3] = weight[q - 1][1] + v * p; 
			}
		}
		// 合并可能出现的商品的价格和满意度
		for (i = 0; i < n; i++)
		{
			if (price[i][0])                  // 该商品是主件 
			{
				for (j = 1; j < 4; j++)       // 只能购买包含主件的商品,合并可能购买的商品价格 
				{
					price[i][j] += price[i][0];
					weight[i][j] += weight[i][0]; 
				}
				for (j = 0; j < 4; j++)       // 剔除为 0 的数据 
				{
					merge_price[count][j] = price[i][j];
					merge_weight[count][j] = weight[i][j];
				}
				count++;
			}	
		}
		/* 数据处理完成 ,动态规划开始 */ 
		for (i = 1; i <= count; i++)                // 对于 1 ~ count 件物品 
		{
			for (j = 10; j <= money; j += 10)
			{
				max = dp[i - 1][j];                // 数量 j 的金钱购买前 i - 1 件已经出现物品最多获得满意度
				/* 开始尝试购买才出现的第 i 件物品(数组下标为 i - 1) */ 
				for (k = 0; k < 4; k++)            // 购买必须包含主件的商品之一,取最大值 
				{
					if (!merge_price[i - 1][k])    // 不存在该组合
						break; 
					if (j - merge_price[i - 1][k] >= 0) // 如果买得起某个组合,比较这笔钱 没花之前的所能购买到的最大满意度加上购买该组合新增的满意度之和 和 不购买该组合之前所得满意度的大小 
						max = MAX(max, dp[i - 1][j - merge_price[i - 1][k]] + merge_weight[i - 1][k]); // dp[i - 1] 指的是已经出现的前 i - 1 个物品的最大满意度,不是第 i 个,回退时金钱和商品编号都要减 
				}
				dp[i][j] = max;                    // 买不起或值会变小则不变,买得起且满意度增加则改变  
				/* 获得尝试购买后的最大满意度,尝试结束 */ 
			}	
		}
		printf("%d\n", dp[count][money]);
	}
	
	return 0;
}

全部评论

相关推荐

11-24 00:11
已编辑
广东工业大学 算法工程师
避雷深圳&nbsp;&nbsp;yidao,试用期&nbsp;6&nbsp;个月。好嘛,试用期还没结束,就直接告诉你尽快找下一家吧,我谢谢您嘞
牛客75408465号:笑死,直属领导和 hr 口径都没统一,各自说了一些离谱的被裁理由,你们能不能认真一点呀,哈哈哈哈哈😅😅😅
点赞 评论 收藏
分享
与火:这不接? 留子的钱不挣白不挣
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
09-30 19:49
起名星人:蛮离谱的,直接要求转投销售
投递汇川技术等公司10个岗位
点赞 评论 收藏
分享
在努力的外卷侠很靠谱:怎么,大家都没保底吗?我这美团已经入职了,不说了,系统派单了。
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务