贪心训练日记

1.陶陶摘苹果luoguP1478
贪心
贪心假设:在所有可以摘到的苹果中,优先选择需要力气小的苹果。
贪心证明:因为要求的是共能摘多少个苹果,所以我们可以将每个苹果的价值都视为1。那么无论是摘比较费劲的苹果还是比较省力的苹果所得到的价值都是一样的。但如果摘比较省力的苹果,就可以留下更多的力气去摘其他的苹果。

#include<iostream>
#include<algorithm>
using namespace std;
const int N=5100;
int n;
int s;
int a,b;
int y[N],idx=1;

int main(){
	cin>>n>>s>>a>>b;
	for (int i=1;i<=n;i++){
		int high,force;
		cin>>high>>force;
		if (a+b>=high) y[idx++]=force; 	
	}
	sort(y+1,y+idx);
	int ans=0;
	
	for (int i=1;i<idx;i++){
		s-=y[i];
		if (s>=0)
			ans++;
		 
		else	
			break;
	}
	cout<<ans<<endl;
	return 0;
}

2. luoguP1610鸿山洞的灯
贪心
贪心假设:将所以灯按照坐标由小到大排序后,只要有符合条件的灯就将它关闭。
贪心证明:由于已经排完序,所以灯的坐标单调递增。设当前灯i可关闭,i+1也可以关闭,且如果关闭i,则i+1无法关闭,如果关闭i+1,则i无法关闭。那么由于i+1的坐标更靠后,i+1比i更容易满足让其它灯可以关闭的条件。且i与i+1的价值一样(都会使答案+1),所以i+1比i更优,所以应关闭第i盏灯。

#include<bits/stdc++.h>
using namespace std;
int n,dist,a[100002],sum;
int main()
{
	cin>>n>>dist;
	for(int i=1; i<=n; i++)
		cin>>a[i];
	sort(a+1,a+1+n);
	for(int i=2; i<=n-1; i++)
	{
		if(a[i+1]-a[i-1]<=dist)
		{
			a[i]=a[i-1];    
			sum++;
		}
	}
	cout<<sum<<endl;
	return 0;
}

3. luoguP1115最大字段和
前缀和思想+贪心

贪心假设:设sum为当前字段和,ans为当前最大子段和。每输入一个数,sum的值就加上这个数,如果这个数比ans大的话,就将ans更新为sum。判断过后,如果sum<0,则将sum重置为0。(意为重新开始选择一个区间)。

贪心证明:
因为对于每一个sum,我们都在判断其是否<0之前,判断了其是否可以更新ans,所以如果我们可以遍历到所以可行的方案,那么该贪心做法就是成立的。如果sum<0,sum无论是加一个正数还是一个负数,都会是加上的数的值变小,所以不利于ans变大。如果ans>=0那么ans加上一个数,最终得到的值一定会比,加上的数的原数大,更加利于ans变大。
Tip:由于<0的数加上任何数,都会使这个数变小,>0的数加上任何数,都会使这个数变大,所以0常常作为贪心问题中取舍的分界线。

#include <bits/stdc++.h>
using namespace std;
int n,ans,sum,now;
int main()
{
    scanf("%d",&n);
    scanf("%d",&now);
    ans=now;
    if(now>0) sum=now;
    for(register int i=2;i<=n;i++)
    {
        scanf("%d",&now);
        sum+=now;
        if(sum>ans) ans=sum;
        if(sum<0) sum=0;
    }
    printf("%d",ans);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值