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

NYOJ 30 && POJ 1042 Gone Fishing(枚举+贪心)

时间:2015-04-14 21:42:07      阅读:178      评论:0      收藏:0      [点我收藏+]

标签:acm   贪心 枚举   

【题目链接】:Click here~~

【题目大意】:

一个人去钓鱼,在一条单向路上的旁边有n个湖,并且从湖i到湖i+1需要ti的时间,每个湖里面有fi条鱼,每钓一次鱼,鱼会减少di条。在给定时间T内,问如何才能使钓的鱼最多,并记录在各个湖上停留的时间。

【解题思路】

此题细节处理好多麻烦,一定要认真看清题意,POJ WA了无数遍,纠结一天。参考了别人的题解,思路如下:

首先须注意的一点是,John只能向前走,返回的话只会增加John在路上的时间,因而减少他钓鱼的时间。因此此题解题步骤如下:
1、  枚举John经过的最后一个湖,每种情况减去所需步行的时间,剩下的就是钓鱼的时间。
2、  每5分钟选取钓鱼量最多的湖进行钓鱼,直到时间耗尽。
3、  在所有枚举的情况中选择钓鱼量最多的情况,即为问题的最优解。
此题需要注意的几个问题:
1、  如果解不唯一,选择在第一个湖耗时最多的解;如果仍旧存在不惟一解,选择在第二个湖耗时最多的解,以此类推。
2、  随着时间的增加,在某个湖中的钓鱼数可能会出现负数,此时应将该湖中每个时间单位的钓鱼数更新为零。
3、  在测试数据或程序运行的过程中可能出现每个湖鱼数全为0的情况,注意特别处理。

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

【source】黑书贪心第一题

代码:

#include <stdio.h>
#include <math.h>
#include <queue>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn=30;
#define bug  puts("AC >_<")
int _time[maxn],ans[maxn],temp[maxn];
struct node
{
     int FI,DI;
}Lake[maxn],copyLake[maxn],Dist[maxn];
int main()
{
    //freopen("1.txt","r",stdin);
    int Lakenum,t,tot=0;
    while(cin>>Lakenum&&Lakenum)
    {
        int Time;
        cin>>Time;
        Time=Time*60;
        for(int i=0; i<Lakenum; i++) cin>>Lake[i].FI;       //输入FI
        for(int i=0; i<Lakenum; i++) cin>>Dist[i].DI;     //输入DI
        _time[0]=0;
        for(int i=1; i<Lakenum; i++){
            cin>>t;
            _time[i]=_time[i-1]+t*5;            //每个湖的ti

        }                                       //每五分钟选取钓鱼量最大的
        memset(ans,0,sizeof(ans));
        int Max=-1;
        for(int i=0; i<Lakenum; i++){          //开始枚举终点的位置{
            int sum=0,left_time=Time-_time[i];//总时间-路上消耗时间=该湖钓鱼的时间
            memset(temp,0,sizeof(temp));
             memcpy(copyLake,Lake,sizeof(Lake));//复制原先初始值
            while(left_time>0)                //每个湖剩下的能钓鱼的时间,开始捕鱼
            {
                int maxx=0,id=0;
                for(int j=0; j<=i; j++){
                    if(copyLake[j].FI>maxx){   //第一轮判断哪个湖能捕到最多鱼
                        maxx=copyLake[j].FI;
                        id=j;
                    }
                }
                if(maxx==0)                  //时间还剩余,鱼量已经捕完,直接跳出循环
                    break;
                sum+=maxx;
                temp[id]+=5;
                copyLake[id].FI-=Dist[id].DI;//鱼量依次递减
                left_time-=5;
            }
            if(left_time>0)                  //时间还剩余!注意加到第一个湖!坑点!
                temp[0]+=left_time;
            if(sum>Max){                     //第二轮判断,所有枚举状态下捕鱼量最大!
                Max=sum;
                for(int j=0; j<=i; j++)
                    ans[j]=temp[j];
            }
        }
        if(tot>0)                           //输出格式
            printf("\n");
        printf("%d",ans[0]);
        for(int i=1; i<Lakenum; i++)
            printf(", %d",ans[i]);
        printf("\n");
        printf("Number of fish expected: %d\n",Max);
        tot++;
    }
    return 0;
}
/*
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
*/


NYOJ 30 && POJ 1042 Gone Fishing(枚举+贪心)

标签:acm   贪心 枚举   

原文地址:http://blog.csdn.net/u013050857/article/details/45046779

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