贪心算法

贪心算法的本质是将复杂的问题简化为多个小问题,是某种意义上的局部最优解。

贪心算法要满足三个条件:

  1. 判断问题是否可以被划分成多个子问题。
  2. 判断子问题的局部最优解是否得出全局最优解
  3. 子问题必须具有无后效性

贪心算法入门博客

什么是无后效性

今年暑假不AC:节目排序问题

#include<iostream>
#include<stdio.h>
#include<math.h>
#include<algorithm>
const int MAXN=1e5+10; 
using namespace std;

struct programe{
	int si;				//记录节目起始时间
	int ei;				//记录节目结束时间
}stu[MAXN];

int cmp(const programe &a,const programe &b)	//按照结束时间排序
{
	if(a.ei!=b.ei) return a.ei<b.ei;	//如果结束时间不等,则按结束时间将结构体升序排序
	return a.si<b.si; //若结束时间相等,则按开始时间将结构体升序排序
}
int main()
{	
 	int n; 
	while(scanf("%d",&n)!=EOF&&n)
	{
		for(int i=0;i<n;i++)
		{
			scanf("%d%d",&stu[i].si,&stu[i].ei);
		}
		sort(stu,stu+n,cmp);		//排序算法
		int ans=0,tmp=0;			//tmp记录前一个节目的结束时间,即能够符合要求的最晚开始时间
		for(int i=0;i<n;i++)
		{
			if(stu[i].si >= tmp)
			{
				tmp=stu[i].ei;
				ans++;		//记录能观看节目总数
			}
		}
		cout<<ans<<endl;
	}
} 

例题:取快件

#include<iostream>
#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<stdlib.h>
const int MAXN=1e6+5; 
using namespace std;

long long T,n,m,k,f,max1=0;
long long a[MAXN];

int main()
{	
	scanf("%lld",&T);
	while(T--)
	{
		scanf("%lld%lld%lld",&n,&m,&k);	//n个柜子,要去m个快递,密码箱在第k个柜子
		for(int i=0;i<m;i++)
		{
			scanf("%lld",&a[i]);
		}
		sort(a,a+m);//排序贪心,默认升序排序
		max1=k-1;	//第一步定为先走到k柜
		for(int i=1;i<m;i++)
		{
			max1+=2*abs(a[i]-k);	//前m-1个快递情况相同,均为a[i]柜到k柜一个来回
		}
		if(a[0]<k)					//第m个快递分为在k柜左边和右边两种情况
		max1+=k-1;
		else
		max1+=k-1+2*abs(a[0]-k);
		printf("%lld\n",max1);
	}
} 

例题:打怪兽

#include<iostream>
#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<stdlib.h>
const int MAXN=1e4+5; 
using namespace std;

int T,n,m;
long long ans,sum,time;

struct v11{
	int hp,atk;
	long long time;
}monster[MAXN]; 

bool cmp(struct v11 &x,struct v11 &y){
    return (double)x.atk/x.time>(double)y.atk/y.time;
}	//按照怪兽的攻击力和被打死需要的次数的出书除数降序排序
int main()
{	
	int k=1;
	scanf("%d",&T);
	while(T--)
	{
		 ans=0,sum=0;
		 time=0;
		scanf("%d%d",&n,&m);//n为怪兽个数,m为v11的atk 
		for(int i=0;i<n;i++)
		{
			scanf("%d%d",&monster[i].hp,&monster[i].atk);
			monster[i].time=(monster[i].hp-1)/m+1;	//第i个怪兽被打死需要的次数
		}
		sort(monster,monster+n,cmp);	//对结构体排序
		for(int i=0;i<n;i++)
		{
			time=time+monster[i].time;
			ans+=time*monster[i].atk;
		}
		printf("Case #%d: %lld\n",k,ans);
		k++;
	}
	
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值