poj1036Gangsters<DP>

链接:http://poj.org/problem?id=1036

题意:

有个伸缩门,大小在[0,k]内变动,在每个状态处,门的大小既可以 +1 或者 -1,且初始时是在0处,现在有n个高贵度,身材和到来时间不尽相同的人来饭店,求怎样安排门的变化使得能够进去的人的高贵度之和最大;

思路:

比较常见的一种动规,从N个点中选出任意个点,使其价值最大;

先按时间或其他顺序排序,使数据有序化,然后f[i]代表选择该点最大可得到的价值,通过枚举前一个选择的点来得到f[i]的值;

状态方程:dp[i][j]=max(dp[i+1][j],dp[i+1][j-1],dp[i+1][j+1]);

这类选择类的DP基本都这样,唯一要注意的是,这类题目中,最终阶段保存的结果不一定就是最优结果


View Code
 1 #include <cstdio>
 2 #include <iostream>
 3 #include <cstring>
 4 using namespace std;
 5 
 6 const int N=102;
 7 const int T=30002;
 8 int dp[2][N];
 9 bool mark[T];
10 
11 struct Gan
12 {
13     int t, p, s;
14 }g[N];
15 
16 inline int Max( int a, int b )
17 {
18     return a>b?a:b;
19 }
20 
21 int main( )
22 {
23     int n, k, m;
24     while(scanf( "%d%d%d", &n,&k, &m )==3){
25         memset( mark, 0, sizeof mark );
26         for( int i=1; i<=n; ++ i ){
27             scanf( "%d", &g[i].t );
28             mark[g[i].t]=1;
29         }
30         for( int i=1; i<=n; ++ i ){
31             scanf( "%d", &g[i].p );
32         }
33         for( int i=1; i<=n; ++ i ){
34             scanf( "%d", &g[i].s );
35         }
36         memset(dp, 0, sizeof(dp));
37         for( int i=0;i<=m; ++ i ){
38             for( int j=0; j<=i&&j<=k; ++ j ){
39                 int w=0;
40                 if( mark[i] ){
41                     for( int l=1; l<=n; ++ l ){
42                         if( g[l].s==j&& g[l].t==i ){
43                             w+=g[l].p;
44                         }
45                     }
46                 }
47                 if( j==0 )dp[i%2][j]=Max( dp[1-i%2][j], dp[1-i%2][j+1] );
48                 else if( j==k ) dp[i%2][j]=Max( dp[1-i%2][j], dp[1-i%2][j-1] );
49                 else dp[i%2][j] = Max(Max(dp[1-i%2][j], dp[1-i%2][j-1]), dp[1-i%2][j+1]);
50                 dp[i%2][j] += w;        
51             }
52         }
53         int ans=0; 
54         for( int i=0; i<=k; ++ i ){
55             if(ans<dp[m%2][1])ans=dp[m%2][i];
56         }
57         printf( "%d\n", ans );    
58     }
59 
60     return 0;
61 }
原文地址:https://www.cnblogs.com/jian1573/p/2860253.html