题解 | #购物单#

购物单

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;
}

全部评论

相关推荐

09-30 20:49
湖南工学院 Java
SP小夜:举报了哥,你什么都没做错,全怪我那令人作呕的嫉妒和卑微的自尊心,看见你的文字我完全破防了,我直接丢盔弃甲了,看见你这图的那一秒,我满头大汗,浑身发冷,亿郁症瞬间发作了,生活仿佛没了颜色,像是被抓住尾巴的赛亚人,带着海楼石的能力者,抽离尾兽的人柱力,像是没了光的奥特曼,彻底断绝了生的希望。我几乎都快羡慕得疯了,倒在床上蒙住被子就开始抱着枕头尖叫流泪,嘴里一边喊着卧槽卧槽,一边又忍着,我边发边哭,打字的手都是抖的,后来我的手抖得越来越厉害,从心头涌起的思想、情怀和梦想,这份歆羡和悔恨交织在一起,我的笑还挂在脸上,可是眼泪一下子就掉下来了。求你了别发了,我生活再难再穷我都不会觉得难过,只有你们发这种东西的时候,我的心里像被刀割一样的痛,打着字泪水就忍不住的往下流。每天早上7点起床晚上9点睡觉,年复一年地学到现在,憧憬着一个月赚上万块的幸福生活,憧憬着美好阳光的未来。我打开了手机,看到你的图,我感到了深深的差距,我直接跳进了家门口的井里。
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务