贪心的应用

贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,算法得到的是在某种意义上的局部最优解 。
链接:https://ac.nowcoder.com/acm/problem/24867
来源:牛客网
题目描述
Each of Farmer John’s N (1 <= N <= 50,000) cows likes to graze in a certain part of the pasture, which can be thought of as a large one-dimeensional number line. Cow i’s favorite grazing range starts at location Si and ends at location Ei (1 <= Si < Ei; Si < Ei <= 100,000,000).
Most folks know the cows are quite selfish; no cow wants to share any of its grazing area with another. Thus, two cows i and j can only graze at the same time if either Si >= Ej or Ei <= Sj. FJ would like to know the maximum number of cows that can graze at the same time for a given set of cows and their preferences.
Consider a set of 5 cows with ranges shown below:
… 1 2 3 4 5 6 7 8 9 10 11 12 13 …
… |----|----|----|----|----|----|----|----|----|----|----|----|----
Cow 1: <=:=> : : :
Cow 2: <:::=>:
Cow 3: : <
> : : :
Cow 4: : : <====:=> :
Cow 5: : : <
> : :

These ranges represent (2, 4), (1, 12), (4, 5), (7, 10), and (7, 8), respectively.
For a solution, the first, third, and fourth (or fifth) cows can all graze at the same time. If the second cow grazed, no other cows could graze. Also, the fourth and fifth cows cannot graze together, so it is impossible for four or more cows to graze.

输入描述:

  • Line 1: A single integer: N
  • Lines 2…N+1: Line i+1 contains the two space-separated integers: Si and Ei
    输出描述:
  • Line 1: A single integer representing the maximum number of cows that can graze at once.
    示例1
    输入
    复制
    5
    2 4
    1 12
    4 5
    7 10
    7 8
    输出
    复制
    3
    题解:贪心算法+排序,注意排序时,应该按右边界从小到大排列,如果右边界,则按左边界从小到大排列。不能按左边界从小到大排列,如例子:
    5
    1 2
    2 7
    3 4
    4 5
    6 7
    此例中正确输出为4,而如果按照左边界排序就会输出3。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll nl=1e5+5;
struct node{
	ll a;
	ll b;
};
bool cmp(node x,node y){
	if(x.b<y.b){
		return true;
	}else if(x.b==y.b&&x.a<y.a){//这里注意
		return true;
	}else{
		return false;
	}
}
node s[nl];
int main(){
    ll n;
    cin>>n;
    ll i,j;
    for(i=0;i<n;i++){
    	cin>>s[i].a;
    	cin>>s[i].b;
    }
    sort(s,s+n,cmp);
    ll maxn=0;
    ll sum=1;
	ll z=0;
		for(j=z+1;j<n;j++){//只便利一遍就行
			if(s[z].b<=s[j].a){
				sum++;
				z=j;
			}
		}
		if(sum>maxn){
			maxn=sum;
		}
	cout<<maxn;
}

删数问题
题目描述
键盘输入一个高精度的正整数 NN(不超过 250250 位),去掉其中任意 kk 个数字后剩下的数字按原左右次序将组成一个新的非负整数。编程对给定的 NN 和 kk,寻找一种方案使得剩下的数字组成的新数最小。
输入格式
nn(高精度的正整数 )。
kk(需要删除的数字个数 )。
输出格式
最后剩下的最小数。
输入输出样例
输入 #1复制
175438
4
输出 #1复制
13
题解:首先在前m+1个数中找最小的数,将其标记并输出,将其前面的数删去就行(设删了l个),然后在标记的后面m-l+1个数中找最小的数,以此类推,直到输出完题目要求的数。
证明:为啥在m+1个数中找,因为如果是m+1+1个数的话,有可能找了m个数后还未找到。
注意:全部删除的情况,前缀为零的情况,没有输出的情况(即输出零)。
代码待更新。。。

#include<iostream>
#include<string>
using namespace std;
int n,k,a[257],rest,t=1,minp,cnt=0;
bool flag=0;
string num;
int main(){
    cin>>num>>k;
    n=num.length();
    for(int i=1;i<=n;++i)a[i]=num[i-1]-'0';
    rest=n-k;
    while(cnt<rest){
        minp=t;
        for(int i=t;i<=k+t;++i)if(a[minp]>a[i])minp=i;
        if(a[minp])flag=1;//当前缀为零时,不输出
        if(flag)cout<<a[minp];
        k-=minp-t;//删除了多少数,每次都不会直接超过要求删除的数,顶多等于,这便是解法的奇妙之处
        t=minp+1;//标记转移到下一个数
        cnt++;//选出一个数
    }
    if(!flag)cout<<0;//所选都是0,即输出零。
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值