poj1042(黑书第一道贪心题)
题意就不说了,主要讲讲思路以及注意的地方。
思路:是按黑书上给出的思路编的,主要是贪心+枚举。因为每个池塘只能走一次,可以枚举前1,2,3,.....n个池塘之间所能钓的最大鱼数。我们可以将路程一次性处理完毕,这样就可以瞬移......每次瞬移到鱼最多的池塘钓鱼就好。有点遗憾,他们说可以用dp做,想了许久,没想明白dp怎么做
注意:这道题目思路很简单,倒是细节处理很麻烦,我因为没有想到一个池塘里面的鱼还可以为负数,就贡献了6次wa.......
还得注意:所有池塘鱼为0;不需要走路就可以到下一个池塘;在某种状态下,这一个状态的最大鱼数等于前面的状态中的最大鱼数,这时候要考虑这种状态下是否有某一个池塘的编号小于前一个池塘或者,是不是同一编号下,这种状态下的那个池塘比前面状态下鱼数要大......可能没有说清楚,具体看代码
1:钓鱼次数大于0才进去循环,而不是!=0时 2:当每次求得的sum和最终结果ans相比时,大于ans直接复制,如果等于的话则一定要比较哪个结果中编号小的池塘呆的时间多。 3:当鱼的数目为负数时,直接将数目变成0,而不是负数(没想通为什么,但如果是负数就是不AC,写完这个我再好好研究下) 4:如果你是用排序的方法确定当前的最大值,最好自己写一个排序算法,因为你必须保证当前选的池塘的鱼的数目不仅是最多的,而且池塘的编号也要是最小的!!!直接用排序算法模板相当危险,我把插入排序改进了,重点是可能有很多值相等的情况,你必须保证你选择的池塘是编号最小的。虽说你可以每次从头搜索,找一个最大的,但会超时。 5:最终结果ans的初值应该是负数,因为很可能、不,是就是会有最终结果为0的情况,所以利用if(sum>ans)判断结果时,ans的初值要是负数 6:数据很变态很无耻,有di[i]=0的情况,鱼的数目不会减少;也有时间等于0的情况;显然也有f[i],t[i]=0的情况,好好想想是否都考虑到了,用数据测试一下就好了 7:输出格式算是个小问题吧,记得有两个回车,最后一个池塘木有逗号。
代码:
View Code
1 #include<iostream> 2 #include<stdio.h> 3 #include<string.h> 4 #include<queue> 5 using namespace std; 6 struct ss 7 { 8 friend bool operator<(const ss a,const ss b) 9 { 10 if(a.sum<b.sum) 11 return 1; 12 else if(a.sum==b.sum&&a.num>b.num) 13 return 1; 14 else 15 return 0; 16 } 17 int num,sum,d; 18 }; 19 struct 20 { 21 int sum,d; 22 }s[50]; 23 int a[50],b[50],t[50]; 24 int main() 25 { 26 int n,h; 27 while(scanf("%d",&n)>0&&n) 28 { 29 int tol=-10,tol1=0; 30 memset(a,0,sizeof(a)); 31 scanf("%d",&h); 32 h=h*12; 33 for(int i=1;i<=n;i++) 34 { 35 scanf("%d",&s[i].sum); 36 if(s[i].sum<0) 37 s[i].sum=0; 38 } 39 for(int i=1;i<=n;i++) 40 scanf("%d",&s[i].d); 41 t[0]=t[1]=0; 42 for(int i=2;i<=n;i++) 43 scanf("%d",&t[i]); 44 for(int i=1;i<=n;i++) 45 { 46 priority_queue<ss>q; 47 int ht=h; 48 tol1=0; 49 memset(b,0,sizeof(b)); 50 for(int j=1;j<=i;j++) 51 { 52 ss node; 53 node.num=j; 54 node.sum=s[j].sum; 55 node.d=s[j].d; 56 ht=ht-t[j]; 57 if(node.sum>0) 58 q.push(node); 59 } 60 while(!q.empty()&&ht>0) 61 { 62 ss node=q.top(); 63 q.pop(); 64 tol1+=node.sum; 65 node.sum-=node.d; 66 b[node.num]++; 67 ht--; 68 if(node.sum>0) 69 { 70 q.push(node); 71 } 72 } 73 if(tol1>=tol) 74 { 75 if(tol1>tol) 76 { 77 tol=tol1; 78 if(ht>0) 79 b[1]+=ht; 80 for(int k=1;k<=n;k++) 81 { 82 a[k]=b[k]; 83 } 84 } 85 else 86 { 87 if(ht>0) 88 b[1]+=ht; 89 for(int k=1;k<=n;k++) 90 { 91 if(a[k]>b[k]) 92 break; 93 else if(a[k]<b[k]) 94 { 95 for(int j=1;j<=n;j++) 96 a[j]=b[j]; 97 break; 98 } 99 } 100 } 101 } 102 } 103 for(int i=1;i<n;i++) 104 printf("%d, ",a[i]*5); 105 printf("%d\n",a[n]*5); 106 printf("Number of fish expected: %d\n\n",tol); 107 } 108 return 0; 109 }
朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。