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;
}