Time Limit: 2000MS | Memory Limit: 32768K | |
Total Submissions: 33972 | Accepted: 10458 |
Description
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.
Input
Output
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.
Sample Input
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
Sample Output
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
Source
East Central North America 1999
题意:
约翰准备钓鱼h小时(1≤h≤16),共有n个池塘(2≤n≤25),这些池塘分布在一条直线上,并且到第一个池塘不费时间,约翰只能从第一个池塘出发,并且只能按池塘顺序钓鱼,并且在每个池塘他都可以呆上任意长的时间,但呆的时间必须为5分钟的倍数(即5分钟为一个单位时间),已知从池塘Li到池塘Li+1要化去约翰ti个单位时间。每个池塘的上鱼率预先也是已知的,池塘Li在第一个单位时间内能钓到的鱼为Fi(0≤Fi≤100),并且每当他在某一个鱼塘呆上一个单位时间后,该鱼塘单位时间内能钓到的鱼将减少一个常数di(0≤di≤100)。现在请你编一个程序计算约翰最多能钓到多少鱼。
思路:
这道题以前写过,不过是用得贪心方法写出来的,最近又看到这道题,发现也能DP来写,所以决定试试手。
首先是处理题目数据,因为题目说了,必须是5分钟的倍数,所以我们把单位一看做5分钟,h小时就是h*12单位时间, 每到一个池塘需要耗费走路时间,所以h(i)=h(i-1)-t【i】 状态dp【i】【j】,代表当到达i池塘并且还剩j单位时间时最多收获量,ss(f)函数代表在这个池塘待f单位时间的收获。所以看状态dp【i】【j】当在i池塘耗时多少单位时值最大,并且需要用cur数组保存当dp【i】【j】有多个一样的最大值时,耗时最小的时间是多少,用来回溯,打印消耗时间。
状态的转移方程: dp【i】【j】=max{ dp【i-1】【k】+ss(k-t【i】-j)} t[ i ]+j <=k<=h(i-1)
最后求出最大值maxx后,需要打印出来每个池塘的消耗时间,并且需要序列字典序最大,这时我们可以用刚刚保存的最小耗时的cur数组来处理,枚举每个(dp【i】【0】==maxx)时,求出第i个池塘~第1个池塘的最小耗时,并且求出来字典序最大的,打印出来就OK了。另外还有一些数据可以参考(在代码下面),如果这些数据可以过,nyoj和nsoj就可以过,但是poj就不一定了,需要你自己找出问题了。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <queue>
#define mem(p,k) memset(p,k,sizeof(p));
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define inf 0xffffffff
#define LL long long
using namespace std;
int dp[40][400],cur[40][400],t[50],f[50],d[50],q[50],p[50];
int ss(int i,int k){//求在第I个池塘钓k时间时的收获
if(f[i]-d[i]*(k-1)<0)k=f[i]/d[i]+1;
return k?(f[i]+f[i]-d[i]*(k-1))*k/2:0;
}
int main()
{
int n;
while(cin>>n&&n){
int h,k,maxx=-1,maxi=0;
cin>>h;
h*=12;
k=h;
mem(dp,0);
mem(cur,0);
mem(q,0);
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=2;i<=n;i++)scanf("%d",t+i);
t[1]=0;//第一个池塘不需要走路,直接赋值为0
for(int i=1;i<=n;i++){
h-=t[i];
if(h<=0)break;
for(int j=0;j<=h;j++){
if(i==1){//因为第一个池塘剩余时间为h,所以不用判断
dp[i][j]=ss(1,h-j);
cur[i][j]=h-j;
continue;
}
for(int k=0;k+j<=h;k++){
if(dp[i][j]<dp[i-1][j+t[i]+k]+ss(i,k)){
dp[i][j]=dp[i-1][j+t[i]+k]+ss(i,k);
cur[i][j]=k;//保存最小耗时
}
}
}
if(maxx<dp[i][0]){
maxx=dp[i][0];
}
}
int tt=0;
//处理一下求字典序最大的,可能你们会想为什么不求最大的钓鱼时间,这样就直接找到了,
//其实这样更简单,但是因为我是从1~n推的,我找不到在最大情况时第一个池塘的状态,所以
//只能求最小值了,如果你是从n~1顺序推的话,求最大钓鱼时间就可以直接找到,并且不用这一步比较久可以直接完成了。
for(int j=1;j<=n;j++){
if(maxx==dp[j][0]){
tt=0;
for(int i=j;i>=1;i--){
if(tt>=k)break;
p[i]=cur[i][tt];
tt+=t[i]+cur[i][tt];
}
for(int i=1;i<=n;i++){
if(p[i]>q[i]){
for(int j=1;j<=n;j++)q[j]=p[j];
break;
}
else if(p[i]<q[i])break;
}
mem(p,0);
}
}
for(int i=1;i<=n;i++){
cout<<q[i]*5;
if(i!=n)cout<<", ";
else cout<<endl;
}
cout<<"Number of fish expected: "<<maxx<<endl<<endl;
}
return 0;
}
测试数据:转自:http://zyj177484.blog.163.com/blog/static/1837942312012117103651121/
2
1
10 1
2 5
2
10
16
68 23 36 95 25 83 77 16 71 5
1 11 17 20 16 73 39 13 57 5
41 86 98 59 39 30 57 12 3
25
13
84 16 30 3 42 50 87 78 32 15 32 6 82 52 14 59 46 50 23 35 44 39 100 64 62
6 5 4 0 12 40 6 5 18 12 0 0 76 19 12 6 34 45 12 1 24 13 46 27 44
25 50 66 48 30 72 84 27 41 44 88 18 43 27 49 98 5 21 39 96 97 20 65 94
8
14
96 31 11 23 83 8 73 19
25 3 10 11 19 4 10 19
89 53 42 70 43 1 74
25
14
64 42 25 3 88 45 69 69 69 23 25 6 17 25 44 86 76 75 13 36 76 42 6 83 70
18 24 4 1 68 29 7 20 37 23 16 6 3 5 9 6 71 67 2 3 35 21 2 59 66
25 33 89 47 63 80 93 19 30 54 79 9 30 99 11 91 14 36 33 18 37 77 25 72
14
6
11 45 14 17 44 63 54 62 95 37 31 34 45 35
9 8 3 14 21 55 45 28 87 19 17 21 39 32
49 99 68 64 15 43 79 43 4 74 38 12 22
16
4
23 71 44 74 95 61 4 59 28 14 10 70 48 89 22 26
8 26 30 13 47 25 1 56 25 4 9 28 22 85 17 10
59 37 34 22 19 6 40 72 71 32 7 23 15 50 85
23
6
9 46 42 0 48 67 95 63 58 81 73 24 3 97 67 5 59 0 31 87 36 14 67
1 5 13 0 34 40 5 39 21 77 5 17 3 37 0 5 16 0 24 41 18 10 5
74 2 77 68 17 3 18 56 12 71 71 42 83 54 32 29 41 3 46 83 60 30
18
4
22 55 21 48 3 50 10 43 100 26 50 39 0 21 42 60 64 71
0 34 11 4 3 37 1 38 72 16 24 14 0 10 34 38 14 62
42 99 56 29 57 92 2 77 96 95 49 31 40 90 41 39 18
22
12
9 51 13 98 2 88 76 81 95 18 41 56 88 58 28 87 19 79 68 27 79 42
7 13 8 1 2 6 24 19 78 3 38 38 31 44 15 43 12 19 28 8 71 9
4 95 28 58 43 56 24 82 41 75 4 27 99 98 37 64 31 37 56 28 18
5
9
36 55 9 86 70
6 43 8 52 67
49 19 32 99
25
9
29 56 1 9 23 100 42 63 19 3 42 80 31 22 93 100 27 64 53 10 2 20 41 48 48
25 42 1 2 18 36 8 25 3 2 2 50 2 22 64 6 12 30 49 6 2 9 26 25 22
27 54 71 31 34 69 59 49 12 47 76 71 24 27 61 43 43 72 99 16 89 29 17 42
18
15
98 12 56 18 51 93 80 31 38 37 35 60 48 56 40 60 32 79
55 11 4 10 25 55 48 27 22 6 34 5 8 13 40 25 3 71
96 52 57 72 34 67 73 1 55 68 22 18 85 51 32 99 93
11
11
33 28 87 23 15 26 20 40 5 68 35
4 1 17 13 4 8 16 27 0 16 15
29 30 27 74 76 50 55 27 69 12
12
13
18 73 82 18 64 31 51 45 1 58 8 45
18 12 70 7 64 5 49 8 1 58 8 32
26 60 35 78 63 32 33 28 49 98 76
9
9
42 63 56 83 73 39 53 28 88
24 23 9 34 68 12 9 24 68
71 42 74 71 18 23 30 54
7
3
39 19 67 35 64 23 82
37 16 20 24 32 7 41
21 24 27 83 20 6
2
12
34 22
2 6
39
10
2
18 37 70 72 1 24 72 45 82 65
18 35 26 52 1 1 56 4 43 17
84 6 32 13 33 38 88 48 56
5
13
85 91 23 9 93
7 54 16 8 27
97 64 79 58
7
5
18 29 78 8 90 100 8
8 11 57 2 5 81 4
6 54 8 1 95 32
6
16
47 5 34 41 51 43
34 1 19 18 19 12
58 97 94 45 52
17
11
12 78 52 30 14 60 5 65 20 6 0 87 89 63 50 42 35
1 8 31 0 14 43 1 31 13 0 0 73 27 46 39 19 28
50 82 70 89 24 9 26 47 82 80 43 63 5 48 46 40
20
8
92 12 56 79 79 97 79 41 29 56 80 24 40 57 26 50 37 39 50 96
5 1 2 15 79 95 36 16 0 53 54 22 30 23 22 18 21 8 27 84
72 68 17 16 95 44 81 41 7 97 31 47 43 79 78 82 33 26 59
7
9
84 72 83 38 38 35 76
39 42 74 35 31 33 36
23 94 81 85 81 23
21
16
33 95 37 78 97 29 95 68 89 15 65 2 47 41 6 21 41 99 57 23 14
7 60 28 11 35 13 38 52 41 2 34 2 4 13 0 11 41 11 7 11 9
33 50 85 73 52 57 18 57 24 20 2 63 43 41 33 7 62 99 58 59
19
10
87 59 74 52 58 59 94 16 21 57 28 12 3 1 20 80 3 50 19
78 11 15 25 56 2 48 15 14 20 21 11 3 1 1 53 0 36 18
36 47 31 65 56 64 27 11 17 20 87 93 40 20 6 51 95 96
13
15
18 63 32 75 36 55 99 35 88 95 93 85 55
0 34 1 27 0 13 73 33 30 82 12 38 24
49 80 59 66 36 63 50 61 84 21 77 21
4
10
23 43 8 37
11 25 1 34
52 33 65
18
4
95 89 81 31 53 48 86 50 56 71 79 31 30 68 48 20 50 89
64 26 10 22 32 7 54 31 23 2 66 29 25 14 10 20 12 50
13 33 10 28 81 9 31 47 14 19 62 98 93 55 31 34 89
13
14
38 61 78 84 36 19 22 39 7 59 33 78 67
19 61 22 70 8 0 19 29 2 22 6 26 39
39 1 72 76 88 27 45 70 26 29 40 72
0
Output:
45, 5
Number of fish expected: 31
305, 10, 10, 0, 0, 0, 0, 0, 0, 0
Number of fish expected: 2408
345, 20, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
Number of fish expected: 792
65, 55, 10, 0, 0, 0, 0, 0
Number of fish expected: 422
45, 10, 35, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
Number of fish expected: 305
85, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
Number of fish expected: 163
240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
Number of fish expected: 45
360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
Number of fish expected: 45
240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
Number of fish expected: 1056
0, 0, 0, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
Number of fish expected: 1530
25, 5, 0, 10, 0
Number of fish expected: 295
120, 10, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
Number of fish expected: 104
80, 10, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
Number of fish expected: 574
50, 140, 30, 10, 0, 0, 0, 0, 0, 0, 0
Number of fish expected: 859
115, 35, 10, 15, 0, 0, 0, 0, 0, 0, 0, 0
Number of fish expected: 404
170, 15, 0, 0, 0, 0, 0, 0, 0
Number of fish expected: 180
65, 10, 0, 0, 0, 0, 0
Number of fish expected: 63
505, 20
Number of fish expected: 358
120, 0, 0, 0, 0, 0, 0, 0, 0, 0
Number of fish expected: 18
285, 10, 0, 0, 0
Number of fish expected: 687
255, 15, 0, 0, 0, 0, 0
Number of fish expected: 84
150, 25, 10, 0, 0, 0
Number of fish expected: 124
360, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
Number of fish expected: 498
90, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
Number of fish expected: 948
415, 10, 0, 0, 0, 0, 0
Number of fish expected: 237
60, 10, 10, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
Number of fish expected: 587
130, 30, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
Number of fish expected: 505
900, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
Number of fish expected: 3240
125, 10, 40, 0
Number of fish expected: 133
155, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
Number of fish expected: 326
245, 5, 20, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0
Number of fish expected: 396