算法导论_第16章_贪心算法

本文通过实例解析贪心算法和动态规划的区别与应用。以糖果分配和活动选择问题为例,展示如何运用贪心策略寻找局部最优解,以及如何利用动态规划求全局最优解。同时强调贪心算法并不总是能得到全局最优解,而动态规划则能确保找到最佳解决方案。
摘要由CSDN通过智能技术生成


前言

  本文大部分是观看B站视频后记录的笔记,因此为了偷懒,本文有大量的截图,看着不舒服的话可以去看原视频。

一、贪心算法

  贪心算法,顾名思义,贪心就完事了。对于这种抽象的算法,我的一贯想法是通过实例将其具体化。下面给出一个例子,好好感受:
在这里插入图片描述
  上题的解如下:

//2021.3.8
//钞票支付问题(动态规划法也可解)
//对于此问题需要注意的是,贪心法可能得出最优也可能无法得出全局最优,这取决于硬币的种类

#include<iostream>
#include<vector>
using namespace std;

int main()
{
	vector<int> RMB = { 200,100,20,10,5,1 };   //硬币的币值
	int NUM = RMB.size();    //币值种类
	int x = 628;    //需要支付的总价值
	int count = 0;  //计数,记录支付的硬币数
	for (int i = 0; i < NUM; i++)
	{
		int use = x / RMB[i];
		count += use;
		x = x - RMB[i] * use;
	}
	cout << "总共需要" << count << "张" << endl;
	return 0;
}

  贪心法:每一步都做出当时看起来是最佳的选择。(注:有时候贪心算法可能无法选到全局最优的解。)

二、动态规划例题

1.分糖果

  显然光看字面上对贪心法的描述你可能觉得你懂了,实际上做题后又一头雾水,下面结合一些例子我们对贪心算法做更深入的学习。
题目:
在这里插入图片描述
题目分析:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
贪心规则:用更小的糖果满足小孩。

//2021.3.8
//糖果分配问题

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

int main()
{
	vector<int> g = {5,10,2,9,15,9};      //孩子的需求
	vector<int>	s = {6,1,20,3,8};      //糖果的大小
	sort(g.begin(), g.end());
	sort(s.begin(), s.end());
	int child = 0;   //child代表已经满足了几个孩子
	int cookie = 0;  //cookie代表已经尝试了几个糖果
	while (cookie <= s.size() - 1 && child <= g.size() - 1)
	{
		if (s[cookie] >= g[child])    
		{
			child++;
		}
		cookie++;
	}

	cout << "能够满足的小孩数量:" << child << endl;

	return 0;
}

2.活动选择问题

题目大意:
在这里插入图片描述
贪心规则:每次找结束时间最小的活动。

//2021.3.8
//活动选择问题

#include<iostream>
#include<vector>

using namespace std;

int main()
{
	vector<int> start = { 1,3,0,5,3,5,6,8,8,2,12 };
	vector<int> end = { 4,5,6,7,8,9,10,11,12,13,14 };
	int now_end;     //已经确定可以进行的活动的结束时间
	int count = 1;   //最早结束的一个活动
	now_end = end[0];  //第一个活动选种,now_end=4,这是其他活动的起始时间限制,必须大于等于4
	for (int i = 1; i < end.size(); i++)
	{
		if (start[i] >= now_end)
		{
			count++;
			now_end = end[i];
		}
	}
	cout << count << endl;
	return 0;
}

结论

  怎么找贪心规则是重点,先这样吧,以后再做到贪心算法的题会更新于此。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值