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

Posted 辉小歌

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第 2 章:初出茅庐初级篇 - 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 章:初出茅庐初级篇 - 2.1 穷竭搜索

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

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

算法第4章小结

面试高级算法梳理笔记

算法导论