http://poj.org/problem?id=1042
题意:
给你n,表示n个池塘
给你h,表示你要钓鱼h小时
接下来n个数,f[i],表示第i个池塘一开始有 f[i]条鱼儿; (即使你钓了x条鱼,这个池塘的鱼儿数量不会变,还是f[i])
接下来n个数,d[i],表示第i个池塘每过5分钟,消失d[i]条鱼儿 (在有人钓鱼的情况下) (题设是有点不切实际,不用理)
接下来n-1个数,表示第i个池塘到第i+1个池塘所花的时间, (注意要从池塘1到池塘5,必须先经过2 3 4)
那么问你,在h小时得到最多的鱼数是多少,并输出在每个池塘所呆的时间。
如果鱼数相同,请输出序号小的池塘尽可能呆得时间多的答案;
直接从正面入手有点麻烦处理,只要是中间还要考虑移动的耗时;
因为最后停在哪个池塘的情况只有n种,
假设停在第i个池塘,我们就可以知道,最终在移动的过程总耗时必然为sum_t[i-1],
那么就剩下res_time=总时间-sum_t[i-1];
这些时间全部可以用来钓鱼,那么问题就简单多了;
我们把每个池塘,每次能钓到鱼(会递减)的数量都存起来,然后降序排序
我们只取前面的鱼来钓,直到res_time耗尽或者鱼全没了。
【要注意 d[i]=0的情况,某个池塘的鱼是不会递减的,要特别处理一下】
然后如果 在res_time还有的情况下,鱼钓完了,根据题目要求,要【序号小的池塘尽可能呆得时间多】
那么我们把剩下的时间全部留在池塘1即可;
因此,我们枚举 最终停在池塘 1到n 的情况,就能得到答案了;
挫代码:
#include <cstdio> #include <cmath> #include <cstring> #include <string> #include <algorithm> #include <iostream> #include <queue> #include <map> #include <set> #include <vector> using namespace std; double eps=0.0000001; struct node { int val,id; node(){} node(int a,int b) {val=a;id=b;} }; node tm[100005]; int cmp(node a,node b) { if (a.val!=b.val) return a.val>b.val; else return a.id<b.id; } int f[30],d[30],t[30]; int sum_t[30]; int sum[30]; int ans_num[30]; int tmp_num[30]; int min(int a,int b){return a<b?a:b;} int main() { int i,j,k,n,h; int maxx; int cnt=1; while(cin>>n&&n) { maxx=-1; cin>>h; h*=12; for (i=1;i<=n;i++) scanf("%d",&f[i]); for (i=1;i<=n;i++) scanf("%d",&d[i]); for (i=1;i<=n-1;i++) { scanf("%d",&t[i]); sum_t[i]=sum_t[i-1]+t[i]; //移动耗时前缀和 } int end; for (end=1;end<=n;end++) { int ok=0; int res_time=h-sum_t[end-1]; //除掉移动花费的时间,剩下的为可以钓鱼的时间 for (i=1;i<=end;i++) //把每一次耗时可能掉的鱼数都放到tm数组 { int tmp=f[i]; while(tmp>0) { tm[++ok].val=tmp; tm[ok].id=i; if (d[i]==0) //当作能钓n次 { for (j=1;j<=h;j++) { tm[++ok].val=tmp; tm[ok].id=i; } break; } tmp-=d[i]; } } sort(tm+1,tm+1+ok,cmp); //降序排序 int len=min(ok,res_time); int ans=0; memset(tmp_num,0,sizeof(tmp_num)); for (i=1;i<=len;i++) { ans+=tm[i].val; tmp_num[tm[i].id]++; } if (ans>=maxx) //大于等于都可能更新 { if (res_time>ok) //如果钓完了鱼还有剩余时间,就把时间全部浪费在第一个鱼塘 { tmp_num[1]+=res_time-ok; } int flag=0; if (ans==maxx) { for (i=1;i<=n;i++) //按找题目要求,鱼数一样取在序号小的鱼塘花费时间较多的答案 { if (tmp_num[i]==ans_num[i]) continue; if (tmp_num[i]<ans_num[i]) {flag=1;break;} if (tmp_num[i]>ans_num[i]) {flag=0;break;} } } if (flag) continue; maxx=ans; memset(ans_num,0,sizeof(ans_num)); for (i=1;i<=n;i++) ans_num[i]=tmp_num[i]; } } if (cnt!=1)printf("\n"); cnt++; for (i=1;i<=n;i++) { if (i!=1) printf(", "); printf("%d",5*ans_num[i]); } printf("\nNumber of fish expected: %d\n",maxx); } return 0; }