24.贪心算法

贪婪算法(贪心算法)是指在对问题进行求解时,在每一步选择中都采取最好或者最优(即最有利)的选择,从而希望能够导致结果是最好或者最优的算法。
请看下面案例,假设有如下课程,希望尽可能多的将课程安排在一间教室里:

课程 开始时间 结束时间
美术 9:00 10:00
英语 9:30 10:30
数学 10:00 11:00
计算机 10:30 11:30
音乐 11:00 12:00

这个问题看似要思考很多,实际上算法很简单:

1.选择结束最早的课,便是要在这教室上课的第一节课

2.接下来,选择第一堂课结束后才开始的课,并且结束最早的课,这将是第二节在教室上的课。

重复这样做就能找出答案,这边的选择策略便是结束最早且和上一节课不冲突的课进行排序,因为每次都选择结束最早的,所以留给后面的时间也就越多,自然就能排下越多的课了。
每一节课的选择都是策略内的局部最优解(留给后面的时间最多),所以最终的结果也是近似最优解(这个案例上就是最优解)。
贪婪算法所得到的结果往往不是最优的结果(有时候会是最优解),但是都是相对近似(接近)最优解的结果。
贪婪算法并没有固定的算法解决框架,算法的关键是贪婪策略的选择,根据不同的问题选择不同的策略。

基本思路
其基本的解题思路为:
●建立数学模型来描述问题
●把求解的问题分成若干个子问题
●对每一子问题求解,得到子问题的局部最优解
●把子问题对应的局部最优解合成原来整个问题的一个近似最优解

完整代码:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#define N 7

int value[N] = { 1, 2, 5, 10, 20, 50, 100 };
int count[N] = { 10, 2, 3, 1, 2, 3, 5 };

/**************************
*对输入的零钱数,找到至少要用的纸币的数量
*参数:
* money - 要找/支付的零钱数
*返回:
* 至少要用的纸币的数量,-1 表示找不开
*************************/
int solve(int money)
{
	int num = 0;
	int i = 0;

	for (i = N - 1; i >= 0; i--)
	{
		int j = money / value[i];
		int c = j > count[i] ? count[i] : j;

		money -= c * value[i];
		num += c;
	}

	if (money > 0) num = -1;

	return num;
}

int main()
{
	int money = 0;
	int num = 0;

	printf("请输入要支付的零钱的数额:\n");
	scanf_s("%s", &money);

	num = solve(money);

	if (num == -1) 
	{
		printf("对不起,找不开\n");
	}
	else 
	{
		printf("成功的使用至少%d 张纸币实现找零/支付!\n", num);
	}

	system("pause");
	return EXIT_SUCCESS;
}

参考资料来源:

奇牛学院

posted @ 2023-06-25 18:32  CodeMagicianT  阅读(15)  评论(0编辑  收藏  举报