POJ 1042 Gone Fishing(贪心)

题目大意

一个人要去钓鱼,可用时间为h(小时),可选湖泊为n个,可以将湖泊看成在一条直线上的顺序的n个点,要去第k个点必须从第k-1个点出发,所用时间为t[k-1](个5分钟),每个湖初始鱼的数目为f[i](注意,可能为0),每个湖泊单位时间(五分钟)鱼的数目减少d[i]条(这是人在该湖泊钓鱼的情况下,人不在就不会减少),问h时间内他能钓的鱼最多是多少?

题目分析

贪心策略,先找到他能到达的最远的(所有时间用来跑路的极限值)湖泊p,然后分为若干种情况:他的活动范围是 11 、 12 、 ······· 1p,即他可以选择的跑去钓鱼的最远的湖泊有p个,枚举每种情况,把总时间减去跑路的时间就是他能钓鱼的时间,在情况 1k 时,对于每一个单位时间(五分钟),都从1到k枚举每个湖泊找到最大值记录相应位置,然后每种情况都算一次,迭代出最大值就可以了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/*
poj 1042
236K 47MS
*/

#include<cstdio>
#include<cstring>
#include<iostream>

#define MAXN 30

using namespace std;

int f[MAXN],d[MAXN],t[MAXN],n,ans[MAXN],tot[MAXN][200],h;
//tot[i][j]是第i个在湖第j个5分钟能抓的鱼的数目

void init()
{
h *= 12;
for(int i = 1;i <= n;i ++)
scanf("%d",&f[i]);
for(int i = 1;i <= n;i ++)
scanf("%d",&d[i]);
for(int i = 1;i < n;i ++)
scanf("%d",&t[i]);
for(int i = 1;i <= n;i ++)
for(int j = 1;j <= h;j ++)
tot[i][j] = max(f[i] - d[i] * (j - 1) , 0);
}

void calc()
{
int far = 1,tmp[MAXN] = {0},index[MAXN] = {0},sum = -0xfffffff;//可能有全为零的情况
//far为其能到达并钓一会鱼的最远的湖,tmp[i]是从i出发到达下一个湖时用的跑路总时间
//index[i]是指为钓到最多的鱼在第i个湖待的时间
while(far <= n)//计算所能到达的最远的湖
{
tmp[far] = tmp[far-1] + t[far];
if(tmp[far] >= h)
break;
far++;
}
if(far > n)
far = n;
int cnt = 1;
while(cnt <= far)//从近到远试遍所有情况
{
int tsum = 0;
memset(index , 0 , sizeof(index));
int th = h - tmp[cnt-1];//可用钓鱼时间
for(int i = 1;i <= th;i ++)//对于每一个单位时间(五分钟)都寻找最多鱼的湖
{
int tmax = 0,tj = 1;//默认为第一个湖
for(int j = 1;j <= cnt;j ++)//最远到第cnt个湖 cnt∈[1,far]
{
if(tot[j][index[j]+1] > tmax)
{
tj = j;//记录位置
tmax = tot[j][index[j]+1];//记录数目
}
}
tsum += tmax;
index[tj] ++;//在第tj个湖已经待的时间+1
}
if(tsum > sum)//替换
{
sum = tsum;
memcpy(ans , index , sizeof(index));
}
cnt ++;//范围扩大一个湖
}
for(int i = 1;i <= n;i ++)
{
if(i == n)
printf("%d\n",ans[i] * 5);
else
printf("%d, ",ans[i] * 5);
}
printf("Number of fish expected: %d\n\n",sum);
}

int main()
{
freopen("./1042.in" , "r" , stdin);
while(cin>>n>>h)
{
init();
calc();
}
return 0;
}

POJ 1042 Gone Fishing(贪心)

https://rucer.cn/2014-05/poj-1042/

作者

Ferris Tien

发布于

2014-05-01

更新于

2024-10-19

许可协议