算法分析:分析下来,其实是一道枚举+贪心问题,首先枚举钓鱼者可能到达的最大水池,然后总时间减去到达最大水池的时间,接着就可以用贪心法不断地寻找当前拥有最多鱼的水池。值得注意的是使用贪心法有一个好处就是非常容易满足输出要求的条件,而这道题似乎有另外一种解法动态规划则好像需要特殊处理才能够满足这个条件(不过我也没有过多注意DP算法)。
算法实现:调试了好久WA了好几次,第一次是因为忘了每次枚举的时候初始化最初池中的鱼数量;初次WA是初始化最多鱼数量的时候初始化成了0,但其实需要初始化为负数,否则没法输出池子没有鱼的解决方案;第三次……没看清楚输出格式忘了输出两个回车。
代码实现:
#include <iostream>
using namespace std;
int h; //hours
int n; //lakes
int fi[26]; //fishes at first
int cfi[26];
int di[26]; //decrease
int ti[25]; //time between i and i+1
int time; //time cost in traveling
int stay[26]; //time at each lakes
int maxstay[26];
int fish; //fishes
int maxium;
void Fishing(int nn)
{
int tmp=1; //记录当前准备钓鱼湖
int tmpfish=0; //记录所有湖中有最多鱼的
for (int i=1; i<=nn; i++)
if (fi[i]>tmpfish)
{
tmp=i;
tmpfish=fi[i];
}
stay[tmp]++;
fish+=fi[tmp];
fi[tmp]-=di[tmp];
if (fi[tmp]<0)
fi[tmp]=0;
return;
}
int main()
{
while (cin>>n && (n!=0))
{
//初始化
ti[0]=0;
maxium=-1; //初始化为负数才可以
//输入
cin>>h;
h=h*12;
for (int i=1; i<=n; i++)
{
cin>>cfi[i];
}
for (int i=1; i<=n; i++)
{
cin>>di[i];
}
for (int i=1; i<=n-1; i++)
{
cin>>ti[i];
}
//单个枚举
for (int i=1; i<=n; i++)
{
for (int j=1; j<=n; j++)
{
fi[j]=cfi[j];
}
for (int j=1; j<=n; j++)
{
stay[j]=0;
}
fish=0;
time=0;
for (int j=1; j<=i; j++)
{
time+=ti[j-1];
}
if (time>=h)
break;
time=h-time;
while (time--)
{
Fishing(i);
}
if (fish>maxium)
{
for (int k=1; k<=n; k++)
{
maxstay[k]=stay[k];
}
maxium=fish;
}
}
//输出
for (int i=1; i<=n; i++)
{
if (i==1)
{
cout<<maxstay[i]*5;
}
else
{
cout<<", "<<maxstay[i]*5;
}
// printf("%d, ",maxstay[i]*5);
}
cout<<endl;
cout<<"Number of fish expected: "<<maxium<<endl;
cout<<endl;
// printf("%d\nNumber of fish expected: %d\n\n",maxstay[n]*5,maxium);
}
return 0;
}
参考资料:这道题是我在看算法艺术与信息学竞赛的时候的练手题,题目为1.2.2贪心法的例题一。