poj1042 Gone Fishing

http://poj.org/problem?id=1042

题目大意:约翰要去钓鱼。他有h小时可用(1 <= h <= 16),该区域有n个湖泊(2 <= n <= 25),可沿着一条单行道到达。约翰从1号湖出发,但他可以在任何他想要的湖结束。他只能从一个湖到另一个湖,但他不需要在任何一个湖停下来,除非他愿意。对于每个i = 1,…n - 1,从i湖到湖i + 1的5分钟间隔为ti (0 < ti <=192)。例如,t3 = 4意味着从3湖到4湖需要20分钟。为了帮助计划他的钓鱼之旅,约翰收集了一些关于湖泊的信息。对于每个湖i,预计在初始5分钟内捕获的鱼的数量,表示fi(fi >= 0),已知。每5分钟的捕鱼减少了预期在接下来的5分钟内捕获的鱼的数量(di >= 0)。如果预期在间隔内捕获的鱼数量少于或等于di,那么在下一段时间内将不再有鱼留在湖中。为了简化计划,约翰假设没有人会在湖边钓鱼,以影响他想钓到的鱼的数量。

编写一个程序,帮助John计划他的钓鱼之旅,以最大限度地捕获被捕获的鱼的数量。在每个湖上花费的分钟数必须是5的倍数。

也就是说,John要钓到最多的鱼,但是有n个湖,在湖之间位移还需要时间,所以John可能有n种最终停下的位置,我们要去比较这n种情况的钓鱼总数,选出最大的,再输出结果。为了方便表示,我们可以采取碎片化钓鱼,首先把总时间减去走到第p(p<=n)所需要的时间,那么剩余时间都是用来钓鱼的时间,假设John可以瞬间位移,John每次选择剩余最多鱼的湖去钓鱼,这样钓鱼的数目才会达到最多。当然John肯定不会瞬间位移啦,不过没关系,由碎片化钓鱼转化为整体化钓鱼即可。

算法思想:贪心算法,由于John可能在n个湖的任一个位置停下,所以我们要考虑n种情况,并选择出钓鱼总数最多的那种情况。每一种情况都贪心去能钓到最多鱼的湖去钓鱼,若全部鱼都钓完了,就待在第一个湖(案例就是这样)。显然每一次贪心我们要去比较,选出剩余的鱼最多的湖钓鱼,钓完后,相应的期望钓鱼数减少。

#include <iostream>
#include <xmemory>
#include <climits>
#define N 25
using namespace std;
int main(void) 
{
    int n, h;
    int fi[N], di[N], ti[N];//fi[]期望钓鱼数, di[]每五分钟减少鱼数, ti[]位移时间
    int time[N];//在当前湖停下来时在每个湖停留的时间
    int best[N];//最优解对应的在每个湖停留的时间
    int bestFishNum;//最优解钓鱼总数
    int fishNum;//当前钓鱼总数
    while (cin >> n && n)
    {
        cin >> h;
        h *= 12;//共有h个5分钟
        for (int i = 0; i < n; i++) cin >> fi[i];//期望钓鱼数
        for (int i = 0; i < n; i++) cin >> di[i];//每五分钟减少鱼数
        for (int i = 0; i < n - 1; i++) cin >> ti[i];//位移时间
        bestFishNum = INT_MIN;
        memset(best , 0 , sizeof best);
        for (int p = 0; p < n; p++) {//穷举最终停下的湖的位置
            memset(time , 0 , sizeof(time));
            fishNum = 0;
            int remainingTime = h;//当前剩余时间
            int remainingFish[N];//当前在每个湖剩余能钓的鱼的数目
            for (int i = 0; i < n; i++)
                remainingFish[i] = fi[i];//初始化
            for (int j = 0; j < p; j++)
                remainingTime -= ti[j];//先减去路程,之后假设John可以在lake 0到lake i之间随意位移
            while (remainingTime > 0) {//直到时间用尽
                int max = INT_MIN;
                int pos = 0;//当前能钓鱼最多的位置
                for (int j = 0; j <= p; j++)//每次选出能钓鱼最多的位置
                    if (remainingFish[j] > max) 
                    {
                        max = remainingFish[j];
                        pos = j;//找到位置
                    }
                time[pos]++;//对应时间++
                fishNum += remainingFish[pos];//累加钓鱼数
                remainingFish[pos] =remainingFish[pos]- di[pos]>0?remainingFish[pos]-di[pos]:0;
                remainingTime--;
            }
            if (fishNum > bestFishNum)
            {
                bestFishNum = fishNum;
                for (int i = 0; i < n; i++)
                {
                    best[i] = time[i];
                 }
            }
        }
        for (int i = 0; i < n - 1; i++)
            cout << best[i] * 5 << ", ";
        cout << best[n - 1] * 5 << endl;//注意输出格式
        cout << "Number of fish expected: " << bestFishNum << endl << endl;
    }
    return 0;
}
作  者: Angel_Q 出  处:http://www.cnblogs.com/DA799422035/ 关于作者:如有问题或建议,请多多赐教! 版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。 特此声明:所有评论都会在第一时间回复。也欢迎园子的大大们指正错误,共同进步。 声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是作者坚持原创和持续写作的最大动力!
原文地址:https://www.cnblogs.com/DA799422035/p/8961872.html