一看就懂的贪心算法,不懂打我

一看就懂的贪心算法,不懂打我

文章目录

  • 一看就懂的贪心算法,不懂打我
      • 贪心算法的概念
      • 在贪心中如何选择
      • 贪心例题
          • 题目:加工生产调度
          • 思路
          • 代码
      • 小结

贪心(贪婪)算法是一种非常神奇的算法,下面讲解一下:

贪心算法的概念

贪心算法是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解
贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择,选择的贪心策略必须具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关

在贪心中如何选择

贪心选择是指所求问题的整体最优解可以通过一系列局部最优的选择,即贪心选择来达到。这是贪心算法可行的第一个基本要素,也是贪心算法与动态规划算法的主要区别。贪心选择是采用从顶向下、以迭代的方法做出相继选择,每做一次贪心选择就将所求问题简化为一个规模更小的子问题。对于一个具体问题,要确定它是否具有贪心选择的性质,我们必须证明每一步所作的贪心选择最终能得到问题的最优解。通常可以首先证明问题的一个整体最优解,是从贪心选择开始的,而且作了贪心选择后,原问题简化为一个规模更小的类似子问题。然后,用数学归纳法证明,通过每一步贪心选择,最终可得到问题的一个整体次优解(因为不一定是最优)

贪心例题

不管什么算法,没有例题详解都不厉害。下面立刻掏出例题。

题目:加工生产调度

某工厂收到了 n 个产品的订单,这 n 个产品分别在 A、B 两个车间加工,并且必须先在 A 车间加工后才可以到 B 车间加工。
某个产品 i 在 A,B 两车间加工的时间分别为 Ai,Bi。怎样安排这 n 个产品的加工顺序,才能使总的加工时间最短。
这里所说的加工时间是指:从开始加工第一个产品到最后所有的产品都已在 A,B 两车间加工完毕的时间。

Input
第一行仅—个数据 n ,表示产品的数量;
接下来 n 个数据是表示这 n 个产品在 A 车间加工各自所要的时间;
最后的 n 个数据是表示这 n 个产品在 B 车间加工各自所要的时间。

Output
第一行一个数据,表示最少的加工时间;
第二行是一种最小加工时间的加工顺序。

Example
样例输入
5
3 5 8 7 10
6 2 1 4 9

样例输出
34
1 5 4 2 3

Hint
对于 100%的数据, 0

思路

首先嘛,肯定是要让A,B两个车间不要闲下来,最好一直工作,所以A一开始先工作一个最短的给B,最后就是A干完了,看着B继续。。。

代码
#include 
using namespace std;
const int maxn=1000;
struct node{
     
	int a,b,idx;
}e[maxn];
int n,stk[maxn],top;
bool cmp(node& x,node &y){
     
	return min(x.a,y.b)<min(x.b,y.a);
}
void prt(int tb){
     
	cout<<tb<<endl;
	cout<<stk[1];
	for(int i = 2;i<=n;i++){
     
		cout<<" "<<stk[i];
	}
}
void solve(){
     
	int ta=0,tb=0;
	for(int i=1;i<=n;i++){
     
		ta+=e[i].a;
		tb=max(ta,tb)+e[i].b;
		stk[++top]=e[i].idx;
	}
	prt(tb);
}
int main(){
     
	cin>>n;
	for(int i=1;i<=n;i++){
     
		cin>>e[i].a;
	}
	for(int i=1;i<=n;i++){
     
		cin>>e[i].b;
		e[i].idx=i;
	}
	sort(e+1,e+n+1,cmp);
	solve();
	return 0;
}

小结

说到这里大家应该知道了,贪心并不是一种绝对得到最优解的算法,但是在某些题中,比如一道经典的题目:旅行商问题(TSP问题)就要用到。
题目是这样的:
有一个商品推销员,要去若干个城市推销商品。该推销员从一个城市出发,需要经过所有城市后,回到出发地。每个城市之间都有道路连通,且距离各不相同,推销员应该如何选择路线,使得总行程最短呢?
这一题就非常的Bian Tai了,仔细一想,这一题的算法复杂度是O(n!),就是
O(n * (n-1) * (n-2) * … * 3 * 2 * 1)了,这可是指数级别啊!
掏出计算器一按20!=243 2902 0081 7664 0000,态度相当恶劣啊。但是,用贪心就很舒服了,虽然得到的有可能不是最优解,反正也差不了多少~为什么要钻牛角尖捏?在比赛时一部分的最优解题目不会就可以使用贪心来做,有可能会多得到几个的测试点。
在这里插入图片描述

你可能感兴趣的:(算法,信息学)