题目链接:Click here~~
题意:
一个人去钓鱼,在一条单向路上的旁边有n个湖,并且从湖i到湖i+1需要ti的时间,每个湖里面有fi条鱼,每钓一次鱼,鱼会减少di条。
在给定时间T内,问如何才能使钓的鱼最多,并记录在各个湖上停留的时间。
解题思路:
由于走路也需要耗费时间,所以为了争取更多的时间钓鱼,那个人肯定不会走回头路,即每条路花费的时间最多记1次,且剩下的时间即为钓鱼的时间。
所以,我们可以通过枚举他所到达的终点,来确定他路上所花费的时间,也就从而确定了钓鱼的时间。
确定钓鱼时间后,我们则可以根据贪心思想,每次选择鱼最多的那个湖进行钓鱼(因为耗费的时间是一样的)。
#include <queue> #include <stdio.h> #include <string.h> #define bug puts("Ac???") using namespace std; struct Fish { int f,d,id; bool operator < (const Fish& s)const { return f < s.f || f == s.f && id > s.id; } }A[30],R; struct TT { int sum,t[30]; }ans,tmp,NEW; int main() { int n,T,tt[30]; priority_queue <Fish> S; for(int i=1;i<=25;i++) A[i].id = i; tt[1] = 0; while(scanf("%d",&n),n) { ans = NEW; ans.sum = -1; scanf("%d",&T); T *= 12; for(int i=1;i<=n;i++) scanf("%d",&A[i].f); for(int i=1;i<=n;i++) scanf("%d",&A[i].d); for(int i=2;i<=n;i++) { scanf("%d",&tt[i]); tt[i] += tt[i-1]; } for(int j=1;j<=n;j++) //枚举终点 { tmp = NEW; for(int i=1;i<=j;i++) S.push(A[i]); for(int _t=1;_t <= T-tt[j];_t++) { R = S.top(); S.pop(); tmp.sum += R.f; tmp.t[R.id] ++; R.f -= R.d; if(R.f < 0) R.f = 0; S.push(R); } if(tmp.sum > ans.sum) ans = tmp; while(!S.empty()) S.pop(); } for(int i=1;i<n;i++) printf("%d, ",ans.t[i]*5); printf("%d\n",ans.t[n]*5); printf("Number of fish expected: %d\n\n",ans.sum); } return 0; }