码迷,mamicode.com
首页 > 其他好文 > 详细

greedy1042

时间:2014-08-13 12:14:56      阅读:226      评论:0      收藏:0      [点我收藏+]

标签:style   color   os   io   数据   for   ar   问题   

 

题意解释:

John现有h个小时的空闲时间,他打算去钓鱼。钓鱼的地方共有n个湖,所有的湖沿着一条单向路顺序排列(John每在一个湖钓完鱼后,他只能走到下一个湖继续钓),John必须从1号湖开始钓起,但是他可以在任何一个湖结束他此次钓鱼的行程。

此题以5分钟作为单位时间,John在每个湖中每5分钟钓的鱼数随时间的增长而线性递减。每个湖中头5分钟可以钓到的鱼数用fi表示,每个湖中相邻5分钟钓鱼数的减少量用di表示,John从任意一个湖走到它下一个湖的时间用ti表示。

求一种方案,使得John在有限的h小时中可以钓到尽可能多的鱼。

 

选题原因:

经典的贪心例题,采用枚举+贪心的解题思路,题目难度适中。

此题还可以用DP解答,但与贪心相比,过程较复杂。

 

思路:

首先须注意的一点是,John只能向前走,返回的话只会增加John在路上的时间,因而减少他钓鱼的时间。因此此题解题步骤如下:

1、  枚举John经过的最后一个湖,每种情况减去所需步行的时间,剩下的就是钓鱼的时间。

2、  每5分钟选取钓鱼量最多的湖进行钓鱼,直到时间耗尽。

3、  在所有枚举的情况中选择钓鱼量最多的情况,即为问题的最优解。

此题需要注意的几个问题:

1、  如果解不唯一,选择在第一个湖耗时最多的解;如果仍旧存在不惟一解,选择在第二个湖耗时最多的解,以此类推。

2、  随着时间的增加,在某个湖中的钓鱼数可能会出现负数,此时应将该湖中每个时间单位的钓鱼数更新为零。

3、  在测试数据或程序运行的过程中可能出现每个湖鱼数全为0的情况,注意特别处理。

4、  枚举时,结束的标志是剩余时间<=0。

 

代码:

#include <stdio.h>

 

int n;//湖的个数

int h;//可用时间

int fi[30];//最初钓鱼量

int di[30];//单位时间鱼的减少量

int cfi[30];//对 fi 数组的保存

int ti[30];//ti[i] 表示从第 i 个湖到第 i+1 湖的时间

 

struct LAKENODE

{

    int num[30];

    int max;

}lake[30];//用结构体数组保存可能解

 

int GetMax(int p[], int i, int j)//返回数组 p 中最大数的编号

{

    int cmax = p[i], loc = i;// loc :最大数的位置

    for (int m = i + 1; m <= j; m++)

    {

        if (cmax < p[m])

        {

            cmax = p[m];

            loc = m;

        }

    }

    return loc;

}

 

void GetFish()

{

    int i, j;

    int T = h * 60, t, CT;

    for(i = 1; i <= n; i++)//结构体数组初始化,全部置零

    {

        lake[i].max = 0;

        for(int j = 1; j <= n; j++)

        {

            lake[i].num[j] = 0;

        }

    }

    for (i = 1;i <= n; i++)//枚举结束湖的位置,从第一个湖到第n个湖

    {

        CT = T;

        t = 0;

        for (j = 1; j <= i; j++)

        {

            cfi[j] = fi[j];//将fi数组的值拷贝到cfi数组中

            CT = (j < i) ? CT - ti[j] * 5 : CT;//计算除去走路时间后的剩余时间

        }

        while (t < CT)

        {

            int k = GetMax(cfi, 1, i);//找到钓鱼量最多的湖的编号

            lake[i].max += cfi[k];//钓鱼总量增加在k湖一个单位时间钓到的鱼

            lake[i].num[k] += 5;//停在k湖的时间增加一个单位时间

            cfi[k] >= di[k] ? cfi[k] -= di[k] : cfi[k] = 0;//修改第k个湖在下一个时间单位中所能钓到的鱼

            t += 5;//时间增加一个单位时间

        }

    }

    for (i = 1; i <= n; i++)//将最大值拷贝到cfi数组中,用于查询真正最大值

    {

        cfi[i] = lake[i].max;

    }

    int la = GetMax(cfi, 1, n);//la:最优解下标

    for (i = 1; i <= n; i++)

    {

        (i != n) ? printf("%d, ", lake[la].num[i]) : printf("%d", lake[la].num[i]);

    }

    printf("\nNumber of fish expected: %d\n\n", lake[la].max);

}

 

int main()

{

    int i;

    while (scanf("%d", &n) && n)

    {

        scanf("%d", &h);

        for (i = 1; i <= n; i++)

        {

            scanf("%d", &fi[i]);

        }

        for (i = 1; i <= n; i++)

        {

            scanf("%d", &di[i]);

        }

        for (i = 1; i < n; i++)

        {

            scanf("%d", &ti[i]);

        }

        GetFish();

    }

    return 0;

}

 

补充:此解法效率47MS,136K,虽不能达到很高的效率,但整体思路比较直接明确。

 

greedy1042,布布扣,bubuko.com

greedy1042

标签:style   color   os   io   数据   for   ar   问题   

原文地址:http://www.cnblogs.com/notlate/p/3909512.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!