算法_贪心策略

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

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


下一期我们再见

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值