POJ 1042 Gone Fishing (贪心)

来源:互联网 发布:java大数据框架 编辑:程序博客网 时间:2024/05/18 00:47

题目大意:

一个人要去钓鱼,可用时间为h(小时),可选湖泊为n个,可以将湖泊看成在一条直线上的顺序的n个点,要去第k个点必须从第k-1个点出发,所用时间为t[k-1](个5分钟),每个湖初始鱼的数目为f[i](注意,可能为0),每个湖泊单位时间(五分钟)鱼的数目减少d[i]条(这是人在该湖泊钓鱼的情况下,人不在就不会减少),问h时间内他能钓的鱼最多是多少?

题目分析:

贪心策略,先找到他能到达的最远的(所有时间用来跑路的极限值)湖泊p,然后分为若干种情况:他的活动范围是  1~1  、  1~2 、 ·······  1~p,即他可以选择的跑去钓鱼的最远的湖泊有p个,枚举每种情况,把总时间减去跑路的时间就是他能钓鱼的时间,在情况  1~k 时,对于每一个单位时间(五分钟),都从1到k枚举每个湖泊找到最大值记录相应位置,然后每种情况都算一次,迭代出最大值就可以了。

/*poj  1042236K47MS*/#include<cstdio>#include<cstring>#include<iostream>#define MAXN 30using namespace std;int f[MAXN],d[MAXN],t[MAXN],n,ans[MAXN],tot[MAXN][200],h;//tot[i][j]是第i个在湖第j个5分钟能抓的鱼的数目 void init(){h *= 12;for(int i = 1;i <= n;i ++)scanf("%d",&f[i]);for(int i = 1;i <= n;i ++)scanf("%d",&d[i]);for(int i = 1;i < n;i ++)scanf("%d",&t[i]);for(int i = 1;i <= n;i ++)for(int j = 1;j <= h;j ++)tot[i][j] = max(f[i] - d[i] * (j - 1) , 0);}void calc(){int far = 1,tmp[MAXN] = {0},index[MAXN] = {0},sum = -0xfffffff;//可能有全为零的情况 //far为其能到达并钓一会鱼的最远的湖,tmp[i]是从i出发到达下一个湖时用的跑路总时间 //index[i]是指为钓到最多的鱼在第i个湖待的时间 while(far <= n)//计算所能到达的最远的湖 {tmp[far] = tmp[far-1] + t[far];if(tmp[far] >= h)break;far++;}if(far > n)far = n;int cnt = 1;while(cnt <= far)//从近到远试遍所有情况 {int tsum = 0;memset(index , 0 , sizeof(index));int th = h - tmp[cnt-1];//可用钓鱼时间for(int i = 1;i <= th;i ++)//对于每一个单位时间(五分钟)都寻找最多鱼的湖 {int tmax = 0,tj = 1;//默认为第一个湖 for(int j = 1;j <= cnt;j ++)//最远到第cnt个湖  cnt∈[1,far] {if(tot[j][index[j]+1] > tmax){tj = j;//记录位置 tmax = tot[j][index[j]+1];//记录数目 }}tsum += tmax;index[tj] ++;//在第tj个湖已经待的时间+1 }if(tsum > sum)//替换 {sum = tsum;memcpy(ans , index , sizeof(index));}cnt ++;//范围扩大一个湖 }for(int i = 1;i <= n;i ++){if(i == n)printf("%d\n",ans[i] * 5);elseprintf("%d, ",ans[i] * 5);}printf("Number of fish expected: %d\n\n",sum);}int main(){freopen("./1042.in" , "r" , stdin);while(cin>>n>>h){init();calc();}return 0;}


0 0