算法笔记(二)——贪心算法

例题一:http://acm.hdu.edu.cn/showproblem.php?pid=1009(FatMouse' Trade)

      题目大意:老鼠有M磅的猫粮,它可以拿这些去和猫换N磅的食物;食物储存在不同房间,换每个房间的食物所需要的猫粮不同。比如一个房间有a磅食物,需要A磅猫粮,老鼠可以选择把房间里的食物换完(前提是猫粮足够),或者换其中的b磅,那他所需的猫粮为b/a*A磅,求老鼠用这M磅猫粮所能换取的食物最大值。

       解题思路:对输入的各个房间的食物和所需猫粮进行排序,根据食物和猫粮的比值从大到小进行排序,毕竟要换尽可能多的食物,肯定要先换性价比最高的(食物和猫粮比值最大的);然后从大到小开始换食物,换完为止。

AC代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iomanip>
using namespace std;
struct z
{
	double j;//食物
	int f;//猫粮
	double t ;//性价比
};
bool cmp(z a, z b)
{
	return a.t > b.t;
}
int main()
{
	int m, n;
	double s;
	while (cin >> m >> n)
	{
		s = 0;
		if (m == -1 && n == -1)
		{
			break;
		}
		z *a = new z[n];
		for (int i = 0; i < n; i++)
		{
			cin >> a[i].j >> a[i].f;
			a[i].t = a[i].j / a[i].f;
		}
		sort(a, a + n, cmp);
		for (int i = 0; i < n; i++)
		{
			if (m>a[i].f)
			{
				m -= a[i].f;
				s += a[i].j;
			}
			else{
				s += (double)m / a[i].f*a[i].j;
				break;
			}
		}
		cout.setf(ios::fixed);
		cout << setprecision(3) << s << endl;
		delete a; 
	}
	return 0;
}

 

例题二:http://acm.hdu.edu.cn/showproblem.php?pid=1257(最少拦截系统)

       题目已经是中文了,大意就不讲了。

       解题思路:输入的第一个导弹高度直接存为第一个拦截系统的拦截高度;之后对输入的每一个导弹高度和已经使用的拦截系统的拦截高度进行比较,如果找不到拦截高度大于或者等于该导弹的高度的拦截系统,那么就新增一个拦截系统,记录拦截高度;如果找得到可以用的拦截系统,那么就在这些拦截系统里找拦截高度最接近导弹高度且高于导弹高度的拦截系统去拦截(毕竟要学会贪嘛,用相近的拦截系统去拦,可以让剩下的拦截系统所能拦截的导弹高度最大化)。

AC代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define MAX 10000 
using namespace std;
int numlj[MAX];
int main(){
	ios::sync_with_stdio(false);
	int n;
	while(cin>>n){
		int lj=1;
		int h;
		cin>>h;
		numlj[0]=h;
		for(int i=1;i<n;i++){
			cin>>h;
			bool flag1=false;
			for(int j=0;j<lj;j++) {
				if(numlj[j]>=h){//直接用找到符合要求的拦截系统中的第一个的原因仔细想想都会懂;
					numlj[j]=h;//存新的拦截系统前提是前面的拦截系统的拦截高度都比导弹高度矮,
					flag1=true;//所以所有的系统拦截高度是依次递增的。
					break;
				}
			}
			if(!flag1){
				numlj[lj++]=h;
			}
		}
		cout<<lj<<endl;
			
	}
	return 0;
}

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值