看了刘汝佳大牛的黑书果然很有体会,虽然很难,但是真的题题经典,一定要坚持坐下去,下面我们来说说贪心法
贪心算法即是每次选择局部最优策略进行实施,而不去考虑对今后的影响。贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择,选择的贪心策略必须具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。
下面来看一个题目:
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 }
时间: 2024-10-19 22:35:00