算法_贪心策略

14天阅读挑战赛
参考 《趣学算法》 陈小玉教授
(入门书籍,对新手很友好,带你走进算法的大门


学习算法之前 : 雄心壮志
现在:

在这里插入图片描述
所以学习算法到底需要不需要天赋呢? 学习算法很吃力,很绝望 怎么办呢?


好了进入正题

贪心策略

  • 一、什么是贪心策略
  • 二、注意事项
  • 三、遵循的原则
  • 三、海盗装古董问题

一、什么是贪心策略

正如起名,贪心,很贪。
	好比我喜欢睡觉,而且特别喜欢,以至于上课我也睡觉,每天都是白日梦。
	又好似我喜欢打游戏,做梦都打游戏。

一个贪心算法总是做出当前最好的选择,也就是说,它期望通过局部最优选择得到全局最优的解决方案。 --《算法导论》

二、注意事项

  • 一旦做出选择,就不可以回溯。
  • 有可能得不到最优解,而是得到最优解的近似解。
  • 选择什么样子的贪心策略直接决定算法的好坏。

三、遵循的原则

有时候,人们无法分清那些问题可以用贪心算法,哪些问题不可以使用。贪心选择,最优子结构 满足这两个性质,就可以使用贪心算法。

1、贪心选择
在这里插入图片描述
2、最优子结构
在这里插入图片描述


理论课结束,让我们开始上机操作吧。

三、海盗装古董问题

问题描述:

	海盗截获了一艘装满各种各样古董的货船,每一件值很多 “马内”(金钱),但是打碎了,就一文不值。
	海盗船虽然很大,但是载重量有限。
	其中一个名叫 “张三” 的海盗说了:我们要尽可能的把古董搬上船,越多越好。

(现在海盗需要你的帮助,我的朋友。)

问题梳理:

	1) 问题是怎么装越多越好,我们最在意的是什么呢? -- 是“个数”
	2) 利用贪心算法:
		我们就挑着重量轻的装,这样我们才能最大的程度上保证个数最多。

程序示例:

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

//古董 
struct Role
{
	double num;		//重量
	char name;	//名称 
}; 
	
//定义排序规则
bool cmp(Role a,Role b) 
{
	if(a.num < b.num) //从小到大排序 
		return a.num < b.num; 
	return a.name > b.name;	//如果重量相等,则按照名称排序。 
} 

int main()
{
	int size; //古董的个数 
	
	//输入古董的个数 
	cout<<"古董的个数:"<<endl;		
	cin>>size;
	
	struct Role r[size];	//保存古董。 
	
	
	double n = 0.0;		//海盗船的重量 
	double temp = 0.0;	//已经装入海盗船的重量
	int size2= size;	//已经装入海盗船的个数 
	char name2[10];		//已装入海盗船古董的名称 
	
	//输入古董的名称、重量、价值 
	int i = 0;
	while(i<size) 
	{
		cout<<"请输入("<<i+1<<")古董名称、重量"<<endl; 
		cin>>r[i].name>>r[i].num;  
		i++;
	}
	
	//输入海盗船的装量 
	cout<<"请输入海盗船的重量:"<<endl;
	cin>>n;
	
	
	//因为我们采用的是贪心策略,对重量进行排序,按照从轻到重。
	sort(r,r+size,cmp);		//升序排列(从轻到重) 
	
	
	for(int i=0;i<size;i++)		
	{ 
		temp += r[i].num;	//海盗船的重量增加 
		if(temp >= n)	//超重
		{
			
			if(temp > n)	//如果超重或等于船的载重 	
			{
				size2 = i;	//装入海盗船的古董个数 
			}else
			{	
				size2 = i+1;	//如果没有超重,则 海盗成功盗走一件. 
				name2[i] = r[i].name;  	//装入海盗床的古董名称。
			} 
			break; 	
		}
		name2[i] = r[i].name;  		//装入海盗船的古董名称。 
	}
	
	cout<<"海盗盗走的古董名称:"<<endl;
	
	//遍历
	for(int i = 0;i<size2;i++) 
		cout<<name2[i]<<endl; 
		
	return 0;
}

运行结果:
在这里插入图片描述


下一期我们再见

Dijkstra算法是一种用于解决单源最短路径问题的经典算法。它可以找到从一个起始节点到其他所有节点的最短路径。Dijkstra算法的基本思想是通过不断更新起始节点到其他节点的距离,逐步确定最短路径。 具体步骤如下: 1. 创建一个距离数组dist[],用于存储起始节点到其他节点的距离。初始时,将起始节点的距离设为0,其他节点的距离设为无穷大。 2. 创建一个集合visited[],用于记录已经确定最短路径的节点。 3. 重复以下步骤,直到所有节点都被访问: a. 从未访问的节点中选择距离最小的节点u,并将其标记为visited[u]。 b. 对于节点u的所有邻居节点v,如果通过u可以获得更短的路径,则更新节点v的距离dist[v]。 4. 最终,dist[]数组中存储的就是起始节点到其他所有节点的最短路径。 贪心策略是一种在每个阶段都选择当前最优解的策略。在贪心算法中,每一步都选择当前状态下最优的解,而不考虑全局最优解。贪心策略通常适用于一些具有最优子结构性质的问题,即通过局部最优解可以得到全局最优解。 Dijkstra算法贪心策略之间的关系在于,Dijkstra算法在每一步都选择当前距离最小的节点作为下一个访问节点,这也是一种贪心策略。然而,需要注意的是,Dijkstra算法是一种正确且有效的最短路径算法,而贪心策略并不一定能够得到全局最优解。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值