题目链接:http://poj.org/problem?id=1042
题目大意:有n个池塘,编号从1-n,有个人从1号塘开始钓鱼,每个池塘刚开始的5分钟内能钓上fi[i]条鱼,之后每过5分钟,能钓上的鱼就减少di[i]条,如果一个人要在某个池塘钓鱼,那么他至少得花费5分钟,再呆下去就是10分钟,,以此类推,除了钓鱼时间外,还有从第i-1号池塘到i号池塘的时间是ti[i-1]*5分钟。人要到达某个池塘,一定得按顺序走(即i,i+1,i+2...)。某个人一共有h*60分钟,问你在这有限时间内,最多能钓到几条鱼,并输出在每个池塘花费的时间。
思路:贪心+枚举
我们知道一共有n个池塘,并且人只能从上一个池塘走到下一个池塘,所以我们枚举人走到最后的池塘i的编号,并用总时间减去从1-i用在走路上面的时间,这样子我们得到的最后的时间就是用在钓鱼上面的。
得到总时间后,我们就在前1-i个池塘中进行贪心,每5分钟选择一个能够钓上来鱼最多的池塘,此时人的转移可以看做是瞬间的,但其实从宏观上来讲,人的转移是有序的,只不过为了得到最多的鱼,我们将人假装看做是瞬间的,实际上做选择的时候就是按顺序来做的。每次选择那个池塘后,我们将该池塘的可钓鱼数-di[i],时间+5,。。。直到把所有时间都花费完。
#include<stdio.h>
#include<iostream>
#include<string>
#include<string.h>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<time.h>
#include<queue>
#include<stack>
#include<iterator>
#include<math.h>
#include<stdlib.h>
#include<limits.h>
#include<set>
#include<map>
//#define ONLINE_JUDGE
#define eps 1e-8
#define INF 0x7fffffff
#define FOR(i,a) for((i)=0;i<(a);(i)++)
#define MEM(a) (memset((a),0,sizeof(a)))
#define sfs(a) scanf("%s",a)
#define sf(a) scanf("%d",&a)
#define sfI(a) scanf("%I64d",&a)
#define pf(a) printf("%d\n",a)
#define pfI(a) printf("%I64d\n",a)
#define pfs(a) printf("%s\n",a)
#define sfd(a,b) scanf("%d%d",&a,&b)
#define sft(a,b,c)scanf("%d%d%d",&a,&b,&c)
#define for1(i,a,b) for(int i=(a);i<b;i++)
#define for2(i,a,b) for(int i=(a);i<=b;i++)
#define for3(i,a,b)for(int i=(b);i>=a;i--)
#define MEM1(a) memset(a,0,sizeof(a))
#define MEM2(a) memset(a,-1,sizeof(a))
const double PI=acos(-1.0);
template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;}
template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}
template<class T> inline T Min(T a,T b){return a<b?a:b;}
template<class T> inline T Max(T a,T b){return a>b?a:b;}
using namespace std;
#define ll __int64
#define N 110
int n,m;
int h;
int fi[N];
int di[N];
int ti[N];
int p[N];
struct Node{
int tm[N];
int mmax;
void clear(){
memset(tm,0,sizeof tm);
mmax=0;
}
}a[N];
int getMax(int x){ //get the id of the pond which we can get the most fish
int mmax=-1;
int flag;
for(int i=1;i<=x;i++){
if(p[i]>mmax){
mmax=p[i];
flag=i;
}
}
return flag;
}
void getResult(){
int total = h*60; //total time
for(int i=0;i<=n;i++)
a[i].clear();
for(int i=1;i<=n;i++){
int tmp = total;
for(int j=1;j<=i;j++){
p[j] = fi[j];
if(j<i)
tmp -= (ti[j])*5; //the time rested to fish(total time - walking time)
}
int s=0;
while(s<tmp){
int id = getMax(i); //for one time,we choose a place which can fish the most fish
a[i].mmax += p[id]; //a[i].mmax denotes the remotest place we can reach is i and the most fish we can have is a[i].mmax
a[i].tm[id] += 5; //at place id we spend 5 minutes
p[id] -= di[id]; //place id decrease fish by di[id]
if(p[id]<0) p[id]=0;
s += 5;
}
}
for(int i=1;i<=n;i++)
p[i] = a[i].mmax; //find the most fish we can get
int flag = getMax(n);
printf("%d",a[flag].tm[1]); //print the time we spend on every pond
for(int i=2;i<=n;i++)
printf(", %d",a[flag].tm[i]);
printf("\n");
printf("Number of fish expected: %d\n",a[flag].mmax);
}
int main(){
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
#endif
// int t;
int flag=0;
while(sf(n)!=EOF && n){
if(flag)printf("\n");
sf(h);
for(int i=1;i<=n;i++)
sf(fi[i]);
for(int i=1;i<=n;i++)
sf(di[i]);
for(int i=1;i<n;i++)
sf(ti[i]);
getResult();
flag=1;
}
return 0;
}