Peter算法小课堂—贪心算法

A greedy algorithm follows heuristic of making the locally optimal choice at each stage with the intent of finding a global optimum.

思维框架:“每次找最……的物品……”

太戈编程2637题

题目描述:

有n个正整数,现在进行若干次操作:每次删去2个数a和b,然后加入1个数a*b+1。反复操作直到只有一个数,求最小剩下几?

怎样贪心呢?就只有两种可能,①每次挑最小的数合并 ②每次挑最大的数合并。假设有三个数a,b,c,且a

代码:

#include 
using namespace std;
int n;
int main(){
	cin>>n;
	multiset s;
	multiset::iterator it;
	for(int i=1;i<=n;i++){
		int x;
		cin>>x;
		s.insert(x);
	}
	for(int i=1;i<=n-1;i++){
		it=s.end();
		it--;
		int a=*it;
		s.erase(it);
		it=s.end();
		it--;
		int b=*it;
		s.erase(it);
		s.insert(a*b+1);
	}
	cout<<*s.begin()<

练习1:太戈编程113

太戈编程1744题

题目描述:

有 n 个人要过河,第i人重w[i]。每艘小船只有2个位置,最大载重为c。求最少要几艘船?

如何贪心呢?答案是“每次挑最轻的人,搭配另1人尽量重,若无人搭配则独自开船”

代码:

#include 
using namespace std;
typedef long long ll;
ll n,c,w[100009];
int main(){
	cin>>n>>c;
	for(ll i=1;i<=n;i++) cin>>w[i];
	sort(w+1,w+1+n);
	ll ans=0;
	ll i=1;j=n;
	while(i

太戈编程655题

题目描述:

有n辆车大甩卖,第i辆车售价a[i]元。有m个人带着现金来申请购买,第i个到现场的人带的现金为b[i]元,只能买价格不超过其现金额的车子。你是大卖场总经理,希望将车和买家尽量多地进行一对一配对,请问最多卖出多少辆车?

怎样贪心呢?答案是“每次挑最昂贵的车,卖给最富有的人,若卖不出去,则便宜些”。

代码不开放……

太戈编程694题

题目描述:

有 N 堆纸牌,编号分别为 1,2,…, N。每堆上有若干张。可以在任一堆上取若干张纸牌,然后移动。 移牌规则为:在编号为 1 堆上取的纸牌,只能移到编号为 2 的堆上;在编号为 N 的堆上取的纸牌,只能移到编号为 N-1 的堆上;其他堆上取的纸牌,可以移到相邻左边或右边的堆上。 现在要求找出一种移动方法,用最少的移动次数使每堆上纸牌数都一样多。输出最少的移动次数,若无解输出-1。

给大家一个概念:集合类问题和序列类问题。集合类问题指不管你怎样调动数据顺序,都不影响结果。序列类问题指不仅要考虑数据的大小,还要考虑数据移动的方向。此题就属于序列类问题。

如何贪心呢?有童鞋会想将纸牌最多的那一堆拆分。比如9 8 17 6,平均数为10,我们就将第三堆分给第一堆1张,给第二堆2张,给第四堆4张,共3次。但考虑一下1 1 17 9 26 6,平均数为10,有两个大于平均数的数,很麻烦。那应该怎样移动呢?

Peter算法小课堂—贪心算法_第1张图片

先看1,与平均数差9,从后面往前补9,变成10

再看10和-8,和为2,与2*10差18,从后面往前补18,变成10

再看10和10和-1,何为19,与3*10差11,从后面往前补11,变成10

我们就以这种思路进行下去就是最优解。

代码:

#include 
using namespace std;
const int N=109;
int n,ans,s[N],a[N];
int main(){
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	for(int i=1;i<=n;i++) s[i]=s[i-1]+a[i];
	itn avg=s[n]/n;
	for(int i=1;i<=n-1;i++){
		if(s[i]!=avg*i) ans++;
	}
	cout<

练习2:太戈编程693题

你可能感兴趣的:(建模,贪心算法,算法)