贪心算法-钓鱼问题

题目:约翰有h(1≤h≤16)个小时的时间,在该地区有n(2≤n≤25)个湖,这些湖刚好分布在一条路线上,该路线是单向的。约翰从湖1出发,他可以在任一个湖结束钓鱼。但他只能从一个湖到达另一个与之相邻的湖,而且不必每个湖都停留。已知在最初5分钟,湖i预计钓到鱼的数量为fi(fi≥0)。以后每隔5分钟,预计钓到鱼的数量将以常数di(di≥0)递减。如果某个时段预计钓到鱼的数量小于或等于di,那么在下一时段将钓不到鱼。为简单起见,假设没有其它的钓鱼者影响约翰的钓鱼数量。
问题分析:在钓鱼的过程中,访问鱼塘的顺序是单向的,只能从一个鱼塘到相邻的下一个鱼塘,并且从一个鱼塘到相邻的下一个鱼塘路程是要耗费时间的。以5分钟为时间周期,每一个时间周期之后鱼塘一个周期钓到鱼的数量就会减少,即每经过5分钟,fi就会减少对应的di,直到fi小于等于di时,下一周期便不会钓到鱼。

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
int n,h,time1[101],t=0,ans=0,sum,temp;
struct lake
{
    int num;
    int lose;
      bool operator < (const lake &a) const {
        return num<a.num;
      }
}l[101];
int main()
{
    priority_queue<lake>q;
    cin>>n>>h;
    h=h*60/5;
    for(int i=1;i<=n;i++)
        cin>>l[i].num;
    for(int i=1;i<=n;i++)
        cin>>l[i].lose;
        time1[0]=0;
        time1[1]=0;
    for(int i=1;i<=n-1;i++)
        cin>>time1[i+1];
    for(int i=1;i<=n;i++)
    {
        t=0;
        temp=h;
        sum=0;
        for(int j=1;j<=i;j++)
            t+=time1[j];
        temp-=t;
        for(int j=1;j<=i;j++)
            q.push(l[j]);
        while(temp)
        {
            lake l1=q.top();
            q.pop();
            if(l1.num<=0)break;
            sum+=l1.num;
            l1.num-=l1.lose;
            q.push(l1);
            temp--;
        }
        while(!q.empty())
        q.pop();
        if(sum>ans)ans=sum;
    }
   cout<<ans<<endl;
    return 0;
}

样例输入

3
1
4 5 6
1 2 1
1 2

样例输出

35

贪心策略:每次选择鱼最多的湖钓一次鱼对于每个湖来说,由于在任何时候鱼的数目只和约翰在该湖里钓鱼的次数有关,和钓鱼的总次数无关,所以这个策略是最优的。一共可以钓鱼time次,每次在n个湖中选择鱼最多的一个湖钓鱼。

数媒202 钱

猜你喜欢

转载自blog.csdn.net/zjsru_Beginner/article/details/119978792