• 黑书贪心例题之钓鱼 poj1042:Gone Fishing


    总时间限制: 2000ms 内存限制: 65536kB
    描述
    John is going on a fishing trip. He has h hours available (1 <= h <= 16), and there are n lakes in the area (2 <= n <= 25) all reachable along a single, one-way road. John starts at lake 1, but he can finish at any lake he wants. He can only travel from one lake to the next one, but he does not have to stop at any lake unless he wishes to. For each i = 1,...,n - 1, the number of 5-minute intervals it takes to travel from lake i to lake i + 1 is denoted ti (0 < ti <=192). For example, t3 = 4 means that it takes 20 minutes to travel from lake 3 to lake 4. To help plan his fishing trip, John has gathered some information about the lakes. For each lake i, the number of fish expected to be caught in the initial 5 minutes, denoted fi( fi >= 0 ), is known. Each 5 minutes of fishing decreases the number of fish expected to be caught in the next 5-minute interval by a constant rate of di (di >= 0). If the number of fish expected to be caught in an interval is less than or equal to di , there will be no more fish left in the lake in the next interval. To simplify the planning, John assumes that no one else will be fishing at the lakes to affect the number of fish he expects to catch. 
    Write a program to help John plan his fishing trip to maximize the number of fish expected to be caught. The number of minutes spent at each lake must be a multiple of 5.
    输入
    You will be given a number of cases in the input. Each case starts with a line containing n. This is followed by a line containing h. Next, there is a line of n integers specifying fi (1 <= i <=n), then a line of n integers di (1 <=i <=n), and finally, a line of n - 1 integers ti (1 <=i <=n - 1). Input is terminated by a case in which n = 0.
    输出
    For each test case, print the number of minutes spent at each lake, separated by commas, for the plan achieving the maximum number of fish expected to be caught (you should print the entire plan on one line even if it exceeds 80 characters). This is followed by a line containing the number of fish expected. 
    If multiple plans exist, choose the one that spends as long as possible at lake 1, even if no fish are expected to be caught in some intervals. If there is still a tie, choose the one that spends as long as possible at lake 2, and so on. Insert a blank line between cases.
    样例输入
    2 
    1 
    10 1 
    2 5 
    2 
    4 
    4 
    10 15 20 17 
    0 3 4 3 
    1 2 3 
    4 
    4 
    10 15 50 30 
    0 3 4 3 
    1 2 3 
    0 
    样例输出
    45, 5 
    Number of fish expected: 31 
    
    240, 0, 0, 0 
    Number of fish expected: 480 
    
    115, 10, 50, 35 
    Number of fish expected: 724 
    来源
    East Central North America 1999

    本题详细思路可以从黑书上得出,使用贪心法可解,但是有一个问题有没搞懂,黑书上写到普通的算法O(kn^2)的复杂度,没有问题,但是用堆为何就降为了O(knlogn)?

    假设使用堆的话,那么一共n次枚举,而每一次枚举中,有k次从堆中取出最小值,但是每次枚举还需要话费时间来建堆,如果只算取最小值的时间复杂度,那么确实是O(knlogn),但是每一次枚举的过程中如果算上建堆的nlogn的时间的话,那么得出的复杂度结果应该是O( n(klogn+nlogn) ) 因为k<n,可以得出复杂度应该为O(n^2 * logn)才对。

    故我使用了最朴素的遍历的方法来取最小值AC了本题。

    贴上代码

    #include <iostream>
    #include <stdio.h>
    #include <memory.h>
    
    
    using namespace std;
    int n;
    int coun[26] = {0}, temp[26]={0}, sum = 0;
    int f[26],d[26],t[26];
    int h = 0;
    
    int main()
    {
        while(cin>>n)
        {
            if(n == 0)
                break;
            memset(f,0,sizeof(f));
            memset(d,0,sizeof(d));
            memset(t,0,sizeof(t));
            scanf("%d",&h);
            h *= 12;
            for(int i = 0; i < n; i ++)
                scanf("%d",&f[i]);
            for(int i = 0; i < n; i ++)
                scanf("%d",&d[i]);
            for(int i = 0; i < n-1; i ++)
                scanf("%d",&t[i]);
            memset(coun,0,sizeof(coun));
            
            sum = -1;
            for(int i = 0; i < n; i ++)
            {
                memset(temp,0,sizeof(temp));
                int tim = 0;
                for(int j = 0; j < i; j ++)
                {
                    tim += t[j];
                }
                tim = h - tim;
                //printf("%d
    ",tim);
                int tf[26];
                memcpy(tf,f,sizeof(tf));
                /*for(int i = 0; i <n; i++)
                    printf("%d
    ",tf[i]);
                 */
                int ts = 0;
                for(int k = 0; k < tim; k ++)
                {
                    int ti = 0; //compute the max lake
                    int tn = 0; // the index
                    for(int j = 0; j <= i; j ++)
                    {    if( tf[j] > ti)
                    {
                        ti = tf[j];
                        tn = j;
                    }
                    }
                    if(ti == 0)
                    {
                        temp[0] += tim - k;
                        break;
                    }
                    ts += ti;
                    tf[tn] -= d[tn];
                    if( tf[tn] < 0 )
                        tf[tn] = 0;
                    temp[tn] ++;
                }
                if(ts > sum)
                {
                    sum = ts;
                    memcpy(coun,temp,sizeof(coun));
                }
            }
            printf("%d",coun[0]*5);
            for(int i = 1; i < n; i ++)
                printf(", %d",coun[i]*5);
            printf("
    ");
            printf("Number of fish expected: %d 
    
    ",sum);
        }
        
        return 0;
    }

    本题要注意到一点点边界问题,我最开始的代码里,在每一次的case里,将sum初始值赋为了0,这会导致一种情况,如果给的例子里所有湖的鱼的数量都为0的话,那么由于if(ts>sum)这个条件(这个条件也不能改为等号,根据题意,在同等产量上应该是前面的湖花的时间尽量长,如果改为等号,则会使在后面湖花费更长时间的策略覆盖掉先前的策略),不会有任何计算结果来赋值给coun[26],输出就会是在每个湖上花的时间是0,而事实却不应该是这样,输出结果应该是在第一个湖上花了所有的时间。故将初始sum=-1.

  • 相关阅读:
    java_IO流之 NIO
    No enclosing instance of type Outer is accessible. Must qualify the allocation with an enclosing instance of type Outer (e.g. x.new A() where x is an instance of Outer)
    JAVA I/O流 之入门
    10年老司机经验总结--程序员兼职的那些事
    python 去除html 超链接href 如何实现?
    《模式分类(原书第二版)》pdf格式下载电子书免费下载
    通知-招财猫问题通知专用
    Centos6.5 安装 python3.5 虚拟环境 virtualenvwrapper
    5.区块链平台以太坊从入门到精通之 以太网区块链网络
    4.区块链平台以太坊从入门到精通之 以太币
  • 原文地址:https://www.cnblogs.com/xiaoshen555/p/3878543.html
Copyright © 2020-2023  润新知