zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    新手入门:python的pip安装(二)
    新手入门:python的安装(一)
    python解释器和环境安装
    Python基础入门总结
    Python环境搭建教程(windows10)
    漏洞重温之sql注入(三)
    漏洞重温之sql注入(二)
    漏洞重温之sql注入(一)
    漏洞重温之文件上传(FUZZ)
    漏洞重温之文件上传(总结)
  • 原文地址:https://www.cnblogs.com/jian1573/p/2860253.html
Copyright © 2011-2022 走看看