2021-10-17

学习《挑战程序设计竞赛》
2.2贪心算法
硬币问题
有1元、5元、10元、50元、100元、500元的硬币各C1 C5 C10 C50 C100 C500 。现在要用这些硬币来支付A元,最少需要多少枚硬币?

#include<iostream>
using namespace std;
const int v[6]={1,5,10,50,100,500};
int C[6];
int A;

void solve()
{
	int ans=0;
	for(int i=5;i>=0;i--)
	{
		int t=min(A/v[i],C[i]);
		A-=t*v[i];
		ans+=t;
		if(t!=0)
		{
			cout<<"需要面值为"<<v[i]<<"的硬币"<<t<<"枚" <<endl; 
		}
	}
	cout<<ans<<endl;
}

int main()
{
	for(int i=0;i<6;i++)
	{
		cin>>C[i];
	}
	cin>>A;
	solve();
}

区间调度问题
有n项工作,每项工作分别在si开始,ti结束。对每项工作,你都可以选择参加或不参加,但选择了参加某项工作就必须至始至终参加全程参与,即参与工作的时间段不能有重叠(即使开始的时间和结束的时间重叠都不行)。
按书上讲述的,选择算法一:每次都选取结束时间最早的工作

#include<iostream>
#include<algorithm>
#define MAX 10000 
using namespace std;

int N,S[MAX],T[MAX];
pair<int,int> p[MAX];

void solve()
{
	for(int i=0;i<N;i++)
	{
		p[i].first=T[i];
		p[i].second=S[i];
	}
	sort(p,p+N);
	int ans=0,t=0;
	for(int i=0;i<N;i++)
	{
		if(t<p[i].second)
		{
			ans++;
			cout<<"选择该从"<<p[i].second<<"开始,到"<<p[i].first<<"结束的工作"<<endl;
			t=p[i].first;
		}
	}
	cout<<ans<<endl;
}

int main()
{
	cin>>N;
	for(int i=0;i<N;i++)
	{
		cin>>S[i];
	}
	for(int i=0;i<N;i++)
	{
		cin>>T[i];
	}
	solve();
}

字典序最小问题
给定长度为N的字符串S,要构造一个长度为N字符串T。T是一个空串,反复执行下列任意操作:

l 从S的头部删除一个字符,加到T的尾部;

l 从S的尾部删除一个字符,加到T的尾部;

目标是要构造字典序尽可能小的字符串T。

可知算法为每次选择较小的字母放在新构成的串中,这里使用STL中deque来实现更加方便

#include<iostream>
#include<deque>
#define MAX 10000 
using namespace std;
int N=0;
deque<char> S,T;
char temp;

void solve()
{
	char p,q;
	while(S.size())
	{
		p=S.front();
		q=S.back();
		if(p<q)
		{
			T.push_back(p);	
			S.pop_front();
		}
		else
		{
			T.push_back(q);	
			S.pop_back();
		}
		for(int i=0;i<T.size();i++)
		{
			cout<<T.at(i);
		}
		cout<<endl;
	}
}

int main()
{
	cin>>N;
	for(int i=0;i<N;i++)
	{
		cin>>temp;
		S.push_back(temp);
	}
	solve();
	return 0;
}

Saruman’s Army
请添加图片描述

#include<iostream>
#include<deque>
#include<algorithm>
#define MAX 10000 
using namespace std;
int N=0,R=0;
int X[MAX];

void solve()
{
	sort(X,X+N);
	int i=0,ans=0;
	while(i<N){
		int s=X[i++];
		while(i<N&&X[i]<=s+R){
			i++;
		}
		int p=X[i-1];
		while(i<N&&X[i]<=p+R){
			i++;
		}
		ans++;
	}
	cout<<ans<<endl;
}

int main()
{
	cin>>N>>R;
	for(int i=0;i<N;i++)
	{
		cin>>X[i];
	}
	solve();
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值