zoukankan      html  css  js  c++  java
  • 基本算法之贪心算法

    看了刘汝佳大牛的黑书果然很有体会,虽然很难,但是真的题题经典,一定要坚持坐下去,下面我们来说说贪心法

         贪心算法即是每次选择局部最优策略进行实施,而不去考虑对今后的影响。贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择,选择的贪心策略必须具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。

    下面来看一个题目:

    POJ1042 钓鱼(黑书)

    链接:http://poj.org/problem?id=1042

     贪心:为了不讨论在路上花费的时间,可以枚举到过的湖:比如:a=j 表示到过湖1、2、..、j相应的, 花在路上的时间
    * 就是 t[1]+t[2]+..+t[j-1] (显然每段路只会走一次) 于是算出time,表示花在钓鱼上的时间,往回走并没有好处,因此我们不选择往回走
    *     这样一来,就不同再考虑路上的时间了,可以认为John有瞬间移动,哪个湖鱼多,就到哪个湖钓(当然 湖的编号 满足 1 <= ~ <=a)

    我们依次枚举究竟要在前多少个湖钓鱼,那么我们可以先将路上的时间计算好,然后人为我们可以在这几个湖之间瞬间转移,每次挑一个上钩率最高的湖去钓即可。

    代码参看的是金海峰大牛,同时学会了新的代码风格,以后将会沿用下去

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<string>
     5 #include<cmath>
     6 #include<cctype>
     7 #include<algorithm>
     8 #include<vector>
     9 #include<map>
    10 #include<stack>
    11 using namespace std;
    12 const int maxn=30;
    13 int f[maxn],d[maxn],t[maxn],ans[maxn];
    14 int n,h,ansf;
    15 bool p=false;
    16 
    17 void init()  //输入部分,用函数更好
    18 {
    19     cin>>h;
    20     h*=12;
    21     ansf=-1;
    22     for(int i=1;i<=n;i++)
    23         cin>>f[i];
    24     for(int i=1;i<=n;i++)
    25         cin>>d[i];
    26     for(int i=1;i<n;i++)
    27         cin>>t[i];
    28 }
    29 
    30 void make(int a,int time)
    31 {
    32     int ls[maxn],ans1[maxn],mx,mxi,fish=0;
    33     memset(ans1,0,sizeof(ans1));
    34     for(int i=1;i<=a;i++)
    35         ls[i]=f[i];
    36     while(time>0)  //此处开始用贪心法,求出最优方案
    37     {
    38         mx=-1;
    39         mxi=-1;
    40         for(int i=1;i<=a;i++)
    41             if(mx<ls[i])
    42         {
    43             mx=ls[i];
    44             mxi=i;
    45         }
    46         fish+=mx;
    47         ans1[mxi]+=1;
    48         ls[mxi]=0>ls[mxi]-d[mxi]?0:ls[mxi]-d[mxi];
    49         time--;
    50     }
    51     if(fish<ansf)
    52         return;
    53     if(fish>ansf)
    54     {
    55         for(int i=1;i<=n;i++)
    56             ans[i]=ans1[i];
    57         ansf=fish;
    58         return;
    59     }
    60     int j=1;
    61     while(j<=n&&ans[j]==ans1[j])
    62         j++;
    63     if(ans1[j]>ans[j])
    64         for(int i=1;i<=n;i++)
    65         ans[i]=ans1[i];
    66 }
    67 void work()
    68 {
    69     int time=0;
    70     t[0]=0;
    71     for(int i=1;i<=n;i++)  //“瞬间转移”经典做法
    72     {
    73         time+=t[i-1];
    74         make(i,h-time);
    75     }
    76 }
    77 
    78 void print()  //输出部分,用函数更好
    79 {
    80     if(p)
    81         cout<<endl;
    82         for(int i=1;i<n;i++)
    83             cout<<ans[i]*5<<", ";
    84         cout<<ans[n]*5<<endl<<"Number of fish expected: "<<ansf<<endl;
    85         p=true;
    86 }
    87 int main()
    88 {
    89     while(cin>>n)
    90     {
    91         if(n==0)
    92             break;
    93         init();
    94         work();
    95         print();
    96     }
    97     return 0;
    98 }
    View Code
  • 相关阅读:
    在 Students 的 Index 页面增加列标题链接(排序),分页,过滤和分组功能
    Contoso 大学
    如何搭建MVC + EF 框架
    EF与手写Model的区别以及联系
    報錯:One or more validation errors were detected during model generation:System.Data.Edm.EdmEntityType: : EntityType 'Movie' has no key
    Oracle四舍五入,向上取整,向下取整
    datagrid中设置编辑,删除列是否可以访问
    datagrid中设置编辑,删除列是否可以访问
    C#实现打印
    C#中rpt的数据类型和Oracle中数据类型的匹配
  • 原文地址:https://www.cnblogs.com/wolf940509/p/4474049.html
Copyright © 2011-2022 走看看