贪心算法

来源:互联网 发布:雷达炒股软件 编辑:程序博客网 时间:2024/06/05 13:34

贪心算法

例题一:FatMouse' Trade

一只老鼠有M磅猫食,然后在N个房间里面用猫食换JavaBean。
房间i中能用F[i]磅的猫食来换J[i]磅的JavaBean,而且老鼠可以在一个房间里根据一定比例a%来换取JavaBean. 现在他是这任务分配给你:告诉他,他的JavaBeans的获取能最多。

输入:The input consists of multiple test cases. Each test case begins with a line containing two non-negative integers M and N. Then N lines follow, each contains two non-negative integers J[i] and F[i] respectively. The last test case is followed by two -1's. All integers are not greater than 1000.

输出:For each test case, print in a single line a real number accurate up to 3 decimal places, which is the maximum amount of JavaBeans that FatMouse can obtain.

结构体和cmp函数:

struct sa {

       int j; // javabeen 的数量

       int f; // 猫食的数量

       double awk; // f[i]/j[i]的比值

       }data[2002];

int cmp( const sa &a,const sa &b)

{

 return (a.awk) > (b.awk);  

}

上面是关于结构体数组定义之类的,下面是主函数,只是一部分不完全

while(scanf(“%d%d”,&m,&n)!=EOF)

  {

    sum=0.0;k=0;

    if (m==-1&&n==-1) break;

    for(int i=0;i<n;i++)

     {

     cin>>data[i].j>>data[i].f;

         data[i].awk=(double)data[i].j/(double)data[i].f ;

     }

     sort(data,data+n,cmp);

for(k=0;k<n;k++)

      {

         if (m>=data[k].f)//大于 F[i]

         {

         sum=sum+data[k].j;  //都换了     

         

          m=m-data[k].f; } 

          else

          {  sum=sum+(double)m*data[k].awk;

            break; } 

          }            

              printf("%.3f\n",sum);            

   } 

补充一下:sort函数默认是从小到大

例题二:时间序列问题

今年暑假不AC(hdu2037)

目标是能看尽量多的完整节目

输入数据包含多个测试实例,每个测试实例的第一行只有一个整数n(n<=100),表示你喜欢看的节目的总数,然后是n行数据,每行包括两个数据Ti_s,Ti_e (1<=i<=n),分别表示第i个节目的开始和结束时间,为了简化问题,每个时间都用一个正整数表示。n=0表示输入结束,不做处理。

对于每个测试实例,输出能完整看到的电视节目的个数,每个测试实例的输出占一行。

struct sa {

       int x;

       int y;

       }data[10000];//又开大了,开101就行

int cmp(const sa &a,const sa &b)

{

    return  a.y < b.y;

    }

sa tmp;

    while(cin>>n&&n!=0)

    {

      sum=0;

      for(int i=0;i<n;i++)

      cin>>data[i].x>>data[i].y;

      sort(data,data+n,cmp);

sum=1;

      tmp=data[0];

      for(int j=1;j<n;j++)

      {

         if (tmp.y<=data[j].x)

         {

           sum++;

           tmp=data[j];                     

          }        

       }

    cout<<sum<<endl;

 

3.区间覆盖问题

Hdu1050

int main(int argc, char *argv[])

{

  int start[401],end[401],data[401];

  int t,n,tmp,aaa;

  cin>>t;

  while(t--)

  {

   cin>>n;

    for(int i=0;i<=400;i++) data[i]=0;

for(int i=0;i<n;i++)

       {

           cin>>start[i]>>end[i];

           if ( start[i]>end[i])

             {tmp=start[i];start[i]=end[i];end[i]=tmp;}         

         if(start[i]%2==1) start[i]=(start[i]+1)/2;

         else start[i]=start[i]/2;

         if (end[i]%2==1) end[i]=(end[i]+1)/2;

         else end[i]=end[i]/2;

         for(int k=start[i];k<=end[i];k++)

           data[k]++;

       }

aaa=data[1];

      for(int j=2;j<=200;j++)

       if (aaa<data[j]) aaa=data[j];

       cout<<aaa*10<<endl;

                       

然而有的区间覆盖的题用上面的那个过不了,会超内存啊,下面介绍的这道题就是如此。

51nod1428

有若干个活动,第i个开始时间和结束时间是[Si,fi),活动之间不能交叠,要把活动都安排完,至少需要几个教室?Input

第一行一个正整数n (n <= 10000)代表活动的个数。

第二行到第(n + 1)行包含n个开始时间和结束时间。

开始时间严格小于结束时间,并且时间都是非负整数,小于1000000000

Output

一行包含一个整数表示最少教室的个数。

Input示例

3

1 2

3 4

2 9

Output示例

2

这道题的精髓就在于数给的很大,数组开不了那么大,那么我们应该如何做呢,看着道题,起点和终点加一起只有20000个点,我们直接离散化,就是把这些点单独拿出来进行操作就行了

精髓是如果只需要教室的个数,我们可以把所有开始时间和结束时间排序,遇到开始时间就把厚度加1,遇到结束时间就把厚度减1,显然最初始和最后结束时的厚度是0,在一系列厚度变化的过程中,峰值(最大值)就是最多同时进行的活动数,也是我们至少需要的教室数。

下面是代码

#include <iostream>

#include <algorithm>

using namespace std;

struct sa

{

    long long xu;

    int v;

}a[20005];

int cmp(const sa&a,const sa&b)

{

    return a.xu<b.xu;

}

int main()

{

    int  s=0,ans=0;

    int n;

    while(cin>>n)

    {

        for(int i=0;i<2*n;i++)

        {

           cin>>a[i].xu;

           if(i%2==0)

            a[i].v=1;

           else a[i].v=-1;

        }

        sort(a,a+2*n,cmp);

        for(int j=0;j<2*n;j++)

        {

            ans+=a[j].v;

            if(ans>s)

                s=ans;

        }

        cout<<s<<endl;

 

    }

    return 0;

}

 

 

 

0 0