:初出茅庐初级篇 - 2.2 贪心算法

Posted 辉小歌

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了:初出茅庐初级篇 - 2.2 贪心算法相关的知识,希望对你有一定的参考价值。

206. 硬币问题 II【简单】


https://www.papamelon.com/problem/206
显而易见的是先用面值大的钞票。

#include<bits/stdc++.h> 
using namespace std;
int a[10],t,n,m;
int b[10]=1,5,10,50,100,500;
int main(void)

	cin>>t;
	while(t--)
	
		for(int i=0;i<6;i++) cin>>a[i];
		cin>>m;
		int cnt=0;
		for(int i=5;i>=0;i--)
		
			int temp=min(m/b[i],a[i]);
			m-=b[i]*temp,cnt+=temp;
		
		cout<<cnt<<endl;
	

212. 区间调度问题【常见模型】


https://www.papamelon.com/problem/212
按照右端点排序。越早选,越早结束。因为我们的右端点是从小到大排序的。

#include<bits/stdc++.h>
using namespace std;
int n,l,r;
int main(void)

	while(cin>>n)
	
		vector<pair<int,int>>ve;
        for(int i=0;i<n;i++)
		
			cin>>l>>r;
			ve.push_back(r,l);
		
		sort(ve.begin(),ve.end());
		int cnt=1;
		r=ve[0].first;
		for(int i=1;i<ve.size();i++)
		
			if(ve[i].second>r)
			
				cnt++;
				r=ve[i].first;
			
		
		cout<<cnt<<'\\n';
	
	return 0;

213. 字典序最小问题 Best Cow Line【有意思的模型】


https://www.papamelon.com/problem/213
本题的关键难点在于,当头尾相同的时候该如何选。
我们需要特别的判断,其剩余字符串正和反的哪个更优。

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n;
char c;
string s,ans;
bool cmp(int l,int r)

	string s1=s.substr(l,r-l+1); 
	string s2=s1;
	reverse(s2.begin(),s2.end());
	if(s1<=s2) return true;
	else return false;

int main(void)

	cin>>n;
	for(int i=0;i<n;i++) cin>>c,s+=c;
	int l=0,r=n-1;
	while(l<=r)
	
		if(s[l]<s[r]) ans+=s[l],l++;
		else if(s[r]<s[l]) ans+=s[r],r--;
		else 
		
			if(cmp(l,r)) ans+=s[l],l++;
			else ans+=s[r],r--;
		
	
	int cnt=0;
	for(int i=0;i<ans.size();i++)
	
		cout<<ans[i];
		cnt++;
		if(cnt%80==0) cout<<endl;
	
	return 0;

214. 萨鲁曼的军队 Saruman’s Army【常见的模型】


https://www.papamelon.com/problem/214

#include<bits/stdc++.h>
using namespace std;
int r,n,x;
int main(void)

	while(cin>>r>>n,r!=-1||n!=-1)
	
		vector<int>ve;
		for(int i=0;i<n;i++) cin>>x,ve.push_back(x);
		sort(ve.begin(),ve.end());
		ve.erase(unique(ve.begin(),ve.end()),ve.end());//去重
		int cnt=0;
		for(int i=0;i<ve.size();i++)
		
			int j=i;
			int len=ve[i]+r;
			while(j+1<ve.size()&&ve[j+1]<=len) j++;//找到最优的点
			len=ve[j]+r;
			while(j+1<ve.size()&&ve[j+1]<=len) j++;//讲当前选的点右边可以覆盖的过滤掉。
			cnt++;
			i=j;
		
		cout<<cnt<<endl;
	
	return 0;

217. 栅栏修理 Fence Repair【常见模型】


https://www.papamelon.com/problem/217
切和合并本质是同一种。就是一个典型的哈夫曼树。

#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
LL n,x,sum;
priority_queue<LL,vector<LL>,greater<LL>>heap;
int main(void)

	cin>>n;
	while(n--) cin>>x,heap.push(x);
	while(heap.size()>1)
	
		auto a=heap.top(); heap.pop();
		auto b=heap.top(); heap.pop();
		sum+=a+b;
		heap.push(a+b); 
	
	cout<<sum;
	return 0;

以上是关于:初出茅庐初级篇 - 2.2 贪心算法的主要内容,如果未能解决你的问题,请参考以下文章

第 2 章:初出茅庐初级篇 - 2.1 穷竭搜索

:初出茅庐初级篇 - 2.3 动态规划

第 2 章:初出茅庐初级篇 - 2.3 动态规划

面试高级算法梳理笔记

算法初级面试题07——前缀树应用介绍和证明贪心策略拼接字符串得到最低字典序切金条问题项目收益最大化问题随时取中位数宣讲会安排

算法_贪心算法篇