首页 > 其他分享 >贪心

贪心

时间:2024-07-08 16:08:40浏览次数:10  
标签:后效 果子 int 线段 sf 贪心

贪心 \(\sf\small\color{gray}Greedy\)

基本思想

贪心,从字面上去理解:
一个人,非常贪心,他不管做出这一步决定后会发生什么,他只管眼前的利益。
这就是贪心。
当然,这个算法的劣处也显现出来:

他不管做出这一步决定后会发生什么。

也就是说,如果这一步片面上是最优的,但会影响到后面酿成严重后果,我们就不能用贪心。
我们把这样的事例称作有 \(\sf\color{red}后效性\) 。
显然,贪心适用于没有后效性的最值问题。
每一次贪下最优的片面抉择,最后,便可算出全局最优。

线段覆盖

现在有 \(\sf n\) 个数轴正半轴上的线段,每个线段的端点是知道的。
这些线段互不能重叠,最多能有多少条线段同时存在?

如果有两条线段 \(\sf(a_1,b_1)\) 和 \(\sf(a_2,b_2)\),那条线段对后面线段放置的影响最小呢?
答案是 \(\sf b\) 小的那个。
因为右边靠左,就留出了更多的空间给后面的线段了。
所以我们只需要给线段们按右端点排序,然后来检查能放几个就好啦。

#include<cstdio>
#include<algorithm>
struct Line
{
	int Start,End;
	bool operator<(Line m)const{return End<m.End;}
}Lines[1000100];
int N;
int main()
{
	scanf("%d",&N);
	for(int i=0;i<N;i++)
		scanf("%d %d",&Lines[i].Start,&Lines[i].End);
	std::sort(Lines,Lines+N);
	int Now=0,Ans=0;
	for(int i=0;i<N;i++)
		if(Now<=Lines[i].Start)
			Ans++,Now=Lines[i].End;
	printf("%d",Ans);
	return 0;
}

合并果子

在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。多多决定把所有的果子合成一堆。
每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和。可以看出,所有的果子经过 \(\sf n-1\) 次合并之后,就只剩下一堆了。多多在合并果子时总共消耗的体力等于每次合并所耗体力之和。
假定每个果子重量都为1,并且已知果子的种类数和每种果子的数目,你的任务是设计出合并的次序方案,使多多耗费的体力最少,并输出这个最小的体力耗费值。

板中板子题。
贪心策略应该很好想:
每次合并最小的两堆,花费的力气就是最小的了。
其实问题在模拟上。
我们可以使用一个小根堆来维护我们的果子堆。

priority_queue< int,vector<int>,greater<int> > a;

每次取出堆顶最小的两个,合并之后在把他装回堆,直到只剩下一堆果子。

#include<cstdio>
#include<queue>
using std::priority_queue;
priority_queue< int,std::vector<int>,std::greater<int> > a;
int N,Ans,o;
int main()
{
	scanf("%d",&N);
	for(int i=0;i<N;i++)
		scanf("%d",&o),
		a.push(o);
	while(a.size()!=1)
	{
		const int o1=a.top();a.pop();
		const int o2=a.top();a.pop();
		a.push(o1+o2);
		Ans+=o1+o2;
	}
	printf("%d",Ans);
	return 0;
}

算法优劣

其实我在开头就说过了:

他不管做出这一步决定后会发生什么。

也就是说,如果这一步片面上是最优的,但会影响到后面酿成严重后果,我们就不能用贪心。
我们把这样的事例称作有 \(\sf\color{red}后效性\) 。 显然,贪心适用于没有后效性的最值问题。
每一次贪下最优的片面抉择,最后,便可算出全局最优。

他不适用于算带后效性的情况,这一点缺,还得请动态规划来填。
还有,大家也看到了,贪心其实和递推一样,码量不大,难的是思维。
所以在用贪心之前,你需要证明,此题贪心无后效性,不然……


完结散花
凑个编辑页面的100行

标签:后效,果子,int,线段,sf,贪心
From: https://www.cnblogs.com/PCwqyy/p/18290108/Greedy

相关文章

  • #贪心#洛谷 3615 如厕计划
    题目传送门分析如果男生数目比女生数目多显然无解,在原队列的基础上考虑调换实际是将男生往前移实际上不满意度就是最后一位女生后移了多少位,记女生为一,男生为负一,运用数学归纳法证明只要后缀最小值不低于负一,那么一定存在一种方案,实际上就是求出后缀最小值,并将其调整至不低......
  • P8298 [COCI2012-2013#2] POPUST (贪心)
    P8298[COCI2012-2013#2]POPUST贪心考虑当前选\(k\)道菜,如果我们先选出了付\(A\)元的菜,那么剩下选\(B\)元的一定是前\(k-1\)大的\(B_i\)。这启发我们先将序列按\(B_i\)排序。那么可以看到两种情况:如果选\(A\)元的菜在\(k\)道菜之外,那么一定选前\(k-1\)道菜......
  • P8453 「SWTR-8」美元巨大 (位运算+贪心)
    P8453「SWTR-8」美元巨大位运算+贪心因为\(a_i=2^{b_i}\),所以每一个符号只会影响一个二进制位,也就是二进制位是独立的。考虑经典的按位考虑,从高位到低位,我们希望高位尽可能取到\(1\)并且留下更好的符号让低位能更大。考虑贪心,显然|比^的价值更大,所以在答案不会变小的情......
  • CF1039D You Are Given a Tree (树形 dp + 贪心 + 根号分治)
    CF1039DYouAreGivenaTree树形dp+贪心+根号分治题目是一个经典问题,可以用树形dp和贪心解决。设\(f_u\)表示以\(u\)节点为端点能够剩下的最长路径。考虑从叶子节点往上合并贪心,那么如果能够合并出包含\(u\)节点的大于等于\(k\)的路径,那么就合并,\(f_u=0\);否......
  • 贪心经典例题:均分纸牌
    希望粉丝破50. 贪心实际上就是把眼前的利益最大化,如果你要做出这道题你一定要找出贪心原则。贪心原则https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=%E8%B4%AA%E5%BF%83%E5%8E%9F%E5%88%99&fenlei=256&rsv_pq=0xb087efe300ab5a2d&rsv_t=78216%2Bh......
  • 贪心推公式——AcWing 125. 耍杂技的牛
    贪心推公式定义贪心算法是一种在每一步选择中都采取在当前状态下最优的选择,希望通过局部的最优选择来得到全局最优解的算法策略。运用情况问题具有最优子结构,即一个问题的最优解包含其子问题的最优解。可以通过局部最优决策逐步推导到全局最优。问题的选择策略相对明确且易......
  • LeetCode 2542. 最大子序列的分数(贪心、小顶堆)
    2542.最大子序列的分数思路:先对nums2按降序排列,然后遍历nums2的最小值,同时在区间[0,i]中选中k个最大的nums1即可。然后找出最大的ansclassSolution{public:typedefpair<int,int>PII;longlongmaxScore(vector<int>&nums1,vector<int>&nums2,intk)......
  • (nice!!!)LeetCode LCP 20. 快速公交(记忆化搜索+小顶堆+贪心)
    LCP20.快速公交思路:逆向记忆化搜索。思考从target到0所花的最小时间。通过哈希表来进行记忆化搜索,避免重复遍历。细节看注释classSolution{public:typedeflonglongLL;typedefpair<LL,LL>PII;constintmod=1e9+7;intbusRapidTransit(int......
  • 蓝桥杯课程-贪心算法讲解
    1.区间调度问题问题描述在有限的区间范围内,选择完成最多的任务组合解决策略我们可以思考的策略有:1.最早开始时间(begin)2.最早结束时间(end)3.用时最少(end-begin)1.我们这里首先定方向:从区间最左端向右开始选择。2.我们很容易想到的策略是选择用时最少的情况,但是试想如果......
  • 小于n的最大数 - 贪心算法及证明 - 附python实现
    一、问题描述?    给定一个整数n,并从1~9中给定若干个可以使用的数字,根据上述两个条件,得到每一位都为给定可使用数字的、最大的小于整数n的数。    例如,给定可以使用的数字为{2,3,8}三个数:    给定n=3589,输出3388;给定n=8234,输出8233;…… 二、解......