贪心算法

贪心算法:

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

        这部博客有相关介绍:点击打开链接

例题:

        之前面试网易时,编程题第三题就是贪心。题目是:有n项工作每项工作分别在Si时间开始,在Ti时间结束。对于每项工作,你都可以选择参与与否。如果选择参与,那么自始至终都必须参与。此外,参与工作的时间段不能重叠。你的目标是参与尽可能多的工作,结果返回最多参与多少项工作。

        限制条件: 1<=N<=100000,1<=Si<=Ti<=109

思路:        

首先,给出3种思想,考虑一下用哪个?

        (1)在可选的工作中,每次都选择开始时间最早的工作。

        (2)在可选的工作中,每次都选择用时最短的工作。

        (3)在可选的工作中,每次都选择与最少可选工作有重叠的工作。 

        (4)在可选的工作中,每次都选择结束时间最早的工作。

下图分别为1,2,3的反例:


所以,正确思路是:先根据工作的结束时间从小到大排序,然后判判断下一个工作的开始时间是否晚于上一个工作的结束时间。(根据结束时间来排序的!只要这个工作能做,绝对是最早结束的)

代码:

#define Max_N 100000

int N,S[Max_N],T[Max_N];
pair<int,int> data[Max_N];	// 一个工作的开始,结束时间为一组

void Solve()
{
	for(int i=0;i<N;i++)
	{
		data[i].first = T[i]; // 按照结结束时间排序,方便起见first用结束时间
		data[i].second = S[i];
	}
	sort(data,data+N);	// 排序
	int Ans = 0;
	int t = 0;
	for(int i=0;i<N;i++)
		if(t < data[i].second)	// 只有t<开始时间才能做该项工作
		{
			Ans++;
			t = data[i].first;	// t换为该项工作的结束时间
		}

	printf("%d\n",Ans);
}

结果:


    选择的是(1,3),(4,7),(8,10)三项工作。

一直向前,贪心~

(刚开始写博客,主要是为了保存一些东西,也分享一些自己的心得,有错误希望指出)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值