十 贪心算法例题


关键在于贪心策略的选择,也就是一个解决问题的思路

1.Team

题目来源,点击查看
题目分析:对于一道题,只要三个人中有两个及以上的人有思路,就能解决这道题目,那么对于给定的n道题目有几道可以做?
解题思路:判断题是否可做(有解题思路的人>=2),可做则数量+1;
代码示例

#include <iostream>
using namespace std;
int main() {
	int n;
	cin>>n; 
	int a[3];
	int sum;
	int number=0;   //解决问题的数量 
	for(int i=0;i<n;i++)
	{
		sum=0;
		for(int i=0;i<3;i++)
		{
			cin>>a[i];
			if(a[i]==1)
				sum++;
		}
		if(sum>=2)  //判断能否解决
			number++;	
	}
	cout<<number;
	return 0;
}

2. Choosing Teams

题目来源,点击查看
题目分析:每个队员最多只能参加5次ACM ICPC,3人一队;给定每个队员参加过该比赛的次数,以及之后需要进行的比赛次数,判断至少能组成几个队伍进行>=k次比赛
解题思路:先判断符合条件的队员(还能比赛次数>=k),之后再看符合条件的人能组成几对
代码示例

#include <iostream>
using namespace std;
int main() {
	int n,k;
	int y[2005];
	cin>>n>>k;
	int sum=0; //符合要求的组队成员 
	for(int i=0;i<n;i++)
	{
		cin>>y[i];
		if(y[i]<=(5-k))
			sum++;
	}
	cout<<sum/3<<endl;
	return 0;
}

3.Feed the cat

题目来源,点击查看
题目分析:需要计算出喂猫的最小花费
解题思路:分为两种情况,一是在8点前醒来,二是在8点或8点后醒来;第一种情况下有直接买和等到8点买两种选择。分别计算在两种情况下的花费,之后找出最小值
代码示例

#include <iostream>
#include <iomanip> //精度头文件 
#include <algorithm>//max min
#include <cmath> //向上取整 
using namespace std;
int main() {
	float hh,mm;
	float h,d,c,n;
	cin>>hh>>mm;
	cin>>h>>d>>c>>n;
	
	float nowMoney=1e9;
	float eightMoney=1e9;
	float afterMoney=1e9;
	
	float time=hh*60+mm;
	//在8点前醒来
	if(time<1200)
	{
		//醒过来直接购买 
		nowMoney=ceil(h/n)*c;  //直接买的钱=需要的面包数量*面包价格
	
		//等到8点再去买8折的猫粮 
		float eh= ((20-hh)*60-mm)*d+h;  //8点的饥饿值 
		eightMoney= ceil(eh/n)*c*0.8;  //8点后买的钱=需要的面包数*八折面包 
	}
	//在8点或者8点后醒来买8折猫粮
	else if(time>=1200)
	{
		afterMoney= ceil(h/n)*c*0.8;
	}
	
	float temp=min(nowMoney,eightMoney);
	float minMoney=min(temp,afterMoney);
	cout<<fixed<<setprecision(4)<<minMoney;
	return 0;
}

4.Even Array理想数组偶数阵列

题目来源,点击查看
题目分析:需要把一个数组变为理想数组(a[i]%2 = i%2),求出所需最小操作数
解题思路:首先找出需要交换的个数,计算奇数位不符合条件的个数odd,偶数位不符合条件的个数even;再判断,如果odd=even,那么表示可以交换,交换个数为odd(even)的个数,若不相等,那么输出-1;
代码示例

#include <iostream>
using namespace std;
int main() {
	int t,n;
	int a[45];
	cin>>t;
	for(int i=0;i<t;i++)
	{
		cin>>n;
		int odd=0;  //奇数位错误个数 
		int even=0;  //偶数位数错误个数 
		//1.计算
		for(int i=0;i<n;i++)
		{
			cin>>a[i];
			//计算错误的奇数和偶数
			//比如若为奇数,那么对应的位置应该也是奇数 
			if(i%2==0 && a[i]%2)
				odd++;
			if(i%2 && a[i]%2==0)
				even++; 
	    }
	    //2.判断
	    //如果错误个数相同,那么就说明可以交换
		//并且交换次数就等于错误个数 
		if(odd == even)
		{
				cout<<odd<<endl;
		}
		else
				cout<<-1<<endl; 
	} 
	return 0;
}

5.今年暑假不AC

题目来源,点击查看
题目分析:给定每个节目的开始时间和结束时间,输出能看到完整电视节目的最多个数
解题思路:按照节目的结束时间进行排序,让每个节目的开始时间和选定的最后一个节目的结束时间对比,若是>=,那么不会重合,那么节目数量num++;
代码示例

#include <iostream>
#include <algorithm>
using namespace std;
typedef struct{
	int Ti_s;  //开始时间
	int Ti_e;  //结束时间
}WTime;

int main() {
	int n;
	WTime Ti[105];
	while(scanf("%d",&n) && n)
	{
		for(int i=0;i<n;i++)
			scanf("%d %d",&Ti[i].Ti_s ,&Ti[i].Ti_e );
		//排序
		//也可尝试用别的方法进行排序
		for(int i=n-1;i>0;i--)
		{
			for(int j=0;j<i;j++)
			{
				if(Ti[j].Ti_e >Ti[j+1].Ti_e )
				{
					WTime temp=Ti[j];
					Ti[j]=Ti[j+1];
					Ti[j+1]=temp;
				}
			}
		 } 
		int num=1;
		int curE=Ti[0].Ti_e ;
		for(int i=0;i<n;i++)
		{
		 	//判断这个节目的开始时间是否>=选定的最后一个节目的结束时间  
			if(Ti[i].Ti_s >=curE)
			{
				num++;
				curE=Ti[i].Ti_e ;
			}
		}
		printf("%d\n",num);	
	}		
	return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值