鱼塘钓鱼(fishing)

来源:互联网 发布:风云无双坐骑通灵数据 编辑:程序博客网 时间:2024/04/29 00:01

给出一个截止时间T(T<1000),设计一个钓鱼方案,从第1个鱼塘出发,希望能钓到最多的鱼。
  假设能钓到鱼的数量仅和已钓鱼的次数有关,且每次钓鱼的时间都是整数分钟。
【输入格式】
  输入文件共5行,分别表示:
  第1行为N;
  第2行为第1分钟各个鱼塘能钓到的鱼的数量,每个数据之间用一空格隔开;
  第3行为每过1分钟各个鱼塘钓鱼数的减少量,每个数据之间用一空格隔开;
  第4行为当前鱼塘到下一个相邻鱼塘需要的时间;
  第5行为截止时间T;
【输出格式】
  输出文件仅一个整数(不超过231-1),表示你的方案能钓到的最多的鱼。
【输入样例】
5
10 14 20 16 9
2 4 6 5 3
3 5 4 4
14
【输出样例】
   76
【知识准备】
最优化原理、贪心法、动态规划、用堆结构实现贪心。
【问题分析】
算法一:
我们可以这样想:如果知道了取到最大值的情况下,人最后在第i个鱼塘里钓鱼,那么用在路上的时间是固定的,因为我们不会先跑到第i个鱼塘里钓一分钟后再返回前面的鱼塘钓鱼,这样把时间浪费在路上显然不划算,再说在你没到某个鱼塘里去钓鱼之前,这个塘里的鱼也不会跑掉(即数量不会减少)。所以这时我们是按照从左往右的顺序钓鱼的,也可以看成路上是不需要时间的,即人可以自由在1~i个鱼塘之间来回走,只要尽可能选取钓到的鱼多的地方就可以了,这就是我们的贪心思想。其实,这个贪心思想并不是模拟钓鱼的过程,只是统计出在各个鱼塘钓鱼的次数。程序实现时,只要分别枚举钓鱼的终
点鱼塘(从鱼塘1到鱼塘n),每次按照上述贪心思想确定在哪些鱼塘里钓鱼,经过n次后确定后最终得到的一定是最优方案。

#include<iostream>#include<cstdio>using namespace std;int a[105],b[105],c[105],v[105];int main(){  freopen("fishing.in","r",stdin);   freopen("fishing.out","w",stdout);   int n;   cin>>n;   for (int i=1;i<=n;++i)   {  cin>>a[i];   }   for (int i=1;i<=n;++i)   cin>>b[i];   for (int i=1;i<=n-1;++i)   {  cin>>c[i];      c[i]=c[i]+c[i-1];        }   int maxxx=0;   int t;cin>>t;   for (int i=1;i<=n;++i)   {  int s=t;      s=s-c[i-1];      int ans=0;      for (int j=1;j<=i;++j)        v[j]=a[j]+b[j];      for (int j=1;j<=s;++j)     {  int maxx=0,xh,y;        for (int k=1;k<=i;++k)        {  y=v[k]-b[k];           if (y>maxx)          { maxx=y;            xh=k;          }        }        v[xh]=v[xh]-b[xh];        ans+=maxx;     }     maxxx=max(maxxx,ans);   }   cout<<maxxx;}

算法二:
  其实,这道题是考虑最优性问题的,所以我们也可以用动态规划来解决,假设用Opt[t][n]来表示第t分钟时,人在第n个鱼塘里钓鱼,最多所能钓到的鱼数。则:
  Opt[t][n] =Maxinum{Opt[t-k][n-1]+S};
  穷举k,S为t-k+1到t之间,除去从第n-1的鱼塘走到第n个鱼塘的时间,在第n个鱼塘中可以钓到的鱼数。
算法三:
  建立以fish为关键字的大根堆,包括能钓到鱼的数量和池塘的编号。然后借助枚举创造条件,实现复杂度为O(m*nlogn)的算法。

2 0
原创粉丝点击