poj 1042 (DP)

Gone Fishing
Time Limit: 2000MS Memory Limit: 32768K
Total Submissions: 33972 Accepted: 10458

Description

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.

Input

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.

Output

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.

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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值