贪心算法的入门题目:在猫食总数为M的前提下,如何才能获得最大的粮食?
按照规则,j[i]*a%可以换取f[i]*a%即f[i]/j[i]的值越小,单位内获取的粮食越大,举例:在M=1时j[1]=7与f[1]=2,和j[2]=4与f[2]=3,肯定是第一组获取获取的多,为sum=1/2*7=3.5,而第二组sum=1/3+4=1.33,这不是重点,重点是这个思想,这类问题可以用贪心的想法解决。
还有活动安排问题,,要求高效的安排一系列公共资源,它不要求问题的整体最优解,但只要遵循一定规则,他一定可以找到整体最优解,一般两个性质:贪心选择和最优子结构。
按照规则,j[i]*a%可以换取f[i]*a%即f[i]/j[i]的值越小,单位内获取的粮食越大,举例:在M=1时j[1]=7与f[1]=2,和j[2]=4与f[2]=3,肯定是第一组获取获取的多,为sum=1/2*7=3.5,而第二组sum=1/3+4=1.33,这不是重点,重点是这个思想,这类问题可以用贪心的想法解决。
还有活动安排问题,,要求高效的安排一系列公共资源,它不要求问题的整体最优解,但只要遵循一定规则,他一定可以找到整体最优解,一般两个性质:贪心选择和最优子结构。
/*************************************************************************
File Name: 1009.cpp
Author: yubo
Mail: yuzibode@126.com
Created Time: 2014年04月12日 星期六 07时45分55秒
学习重点:
************************************************************************/
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<iostream>
using namespace std;
struct Node{
int j;
int f;
double x;
}T[1000];
bool cmp(const Node&a,const Node&b)
{
return a.x<b.x;
}
int main()
{
//freopen("in.txt","r",stdin);
int M,n,i,j,f;
double sum;
while(scanf("%d%d",&M,&n)){
if(M==-1&&n==-1)
break;
sum=0;
for(i=0;i<n;i++)
{
scanf("%d%d",&T[i].j,&T[i].f);
T[i].x=(double)(T[i].f/(T[i].j*1.0));
//printf("%lf\t",T[i].x);
}
sort(T,T+n,cmp);
for(i=0;i<n;i++){
if(M>=T[i].f)
{
M=M-T[i].f;
sum=sum+(double)T[i].j;
}
else
{
sum=sum+(double)(T[i].j/(T[i].f*1.0)*M);
break;
}
}
printf("%0.3lf\n",sum);
}
}