算法笔记学习:入门篇2 贪心(待补充)

简单贪心

贪心法是求解一类最优化问题的方法,它总是考虑在当前状态下局部最优或较优的策略,来使全局达到最优或较优


例题1 【PAT B1020 月饼】
题目描述

现给出所有种类月饼的库存、总售价以及市场的最大需求量,试计算可以获得的最大收益。
注:销售时允许取出一部分库存
案例情形如下:有三种月饼,其库存量分别为18、15、10万吨,总售价分别为75、72、45亿元。若市场需求量只有20万吨,则最大收益策略应当是卖出全部15万吨第二类月饼和5万吨第三种月饼,获得94.5亿元

输入格式

每个输入包含一个测试用例,每个测试用例先给出一个不超过1000的正整数N表示月饼的种类数,以及不超过500(万吨)的正整数D表示市场的最大需求量,随后一行给出N个正数表示表示每种月饼的库存量(万吨);最后一行给出N个整数表示每种月饼总售价(亿元)。数字间以空格分隔

输出用例

对每组测试用例,在一行中输出最大收益,以亿元为单位并精确到小数点后两位

样例输入

3 20
18 15 10
75 72 45

样例输出

94.50

解决方案

思路:
1.采取总是选择单价最高的月饼出售的策略,对每种月饼,根据总售价和库存量获得其单价,并根据单价依次排序
2.从单价高的月饼开始枚举,最后得到的收益即为最大收益

#include<cstdio>
#include<algorithm>

using namespace std;
 
struct mooncake {
	double store;	//库存 
	double sell;	//总售价 
	double price;	//单价 
} cake[1010];

bool cmp(mooncake a, mooncake b)
{
	return a.price > b.price;
}

int main()
{
	int N;
	double D;
	
	scanf("%d %lf",&N,&D);
	
	for (int i = 0; i < N; i++)
	{
		scanf("%lf",&cake[i].store);					//为每种月饼的库存量赋值 
	}
	for (int i = 0; i < N; i++)
	{
		scanf("%lf",&cake[i].sell);						//为每种月饼的总售价赋值 
		cake[i].price = cake[i].sell/cake[i].store;		//获得每种月饼的单价 
	}
	
	sort(cake,cake + N,cmp);							//对cake中mooncake根据单价从高到低排序
	
	double ans = 0; 
	
	for (int i = 0; i < N; i++)
	{
		if (cake[i].store <= D)							//当前月饼库存小于当前需求量 
		{
			D -= cake[i].store;							//更新需求量 
			ans += cake[i].sell;
		}
		else 											//当前月饼库存大于当前需求量 
		{
			ans += cake[i].price * D;
			break;
		}
	}
	
	printf("%.2f",ans);
	
	return 0;
}

例题2 【PAT B1023 组个最小数】
题目描述

给定数字 0 ~ 9 各若干个,可以任意顺序排列这些数字,但必须全部使用。目标是使最后得到的数尽可能的小(0不能作为首位)。现编写程序,使最后得到的数尽可能的小。

输入格式

每个输入包含一个测试用例,每个测试用例在一行中给出是个非负整数,数字表示所拥有的 0 ~ 9 的数字的个数。整数间用一个空格分隔。十个数字的个数不超过50个,且至少包含一个非零数字

输出用例

在一行中输出能够组成的最小数字

样例输入

2 2 0 0 0 3 0 0 1 0

样例输出

10015558

解决方案

思路:
1.由于首位不能为0,因此先从 1 ~ 9 中选出个数不为0的最小数输出。然后从0到9依次将数量不为0的数根据其数目输出

#include<cstdio>

int num[15] = {0};

int main()
{
	int startNum;
	
	for (int i = 0; i < 10; i++)
	{
		scanf("%d",&num[i]);
	}
	
	for (int i = 1; i < 10; i++)
	{
		if (num[i] > 0)
		{
			startNum = i;
			printf("%d",i);
			num[i]--;
			break;
		}
	}
	
	for (int i = 0; i < 10; i++)
	{
		for (int j = 0; j < num[i]; j++)
		{
			printf("%d",i);
		}
	}
	
	return 0;
}

区间贪心(待补充)

区间贪心,即区间不相交问题:给出N个开区间(x,y),从中选择尽可能多的开区间,使得这些开区间之间两两没有交集

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值