zoukankan      html  css  js  c++  java
  • hdu 4374 One hundred layer (dp +单调队列 2012 MultiUniversity Training Contest 8 )

    acm.hdu.edu.cn/showproblem.php?pid=4374

    题意:有n层,每层有m个part。在一层中你只能向着一个方向移动(左或者右),最多能移动T步,

          经过每个部分是都能得到这个部分的分数。起始位置在x位置,从第一层到最顶层能得到最多的分数

    题解:

    dp + 单调队列 ;

    对于 左边我们可以得到  dp[i][j] = max( dp[i - 1][k]  + sum(k, j))       j - t <=k <= j;

    我们的队列 要维护的 就是 

    dp[i - 1][k]  + sum(k, j)
     由于 sum (k ,j) 单调队列要维护的状态必须是和 现在的状态 无关(或着说是 以知的),但 sum(k,j)  用到了现在的状态;

    所以 我们要进行转换一下,   sum(k,j) = sum (1,j) - sum (1,k - 1);

    所以 原式变为    

    dp[i - 1][k]  + sum (1,j) - sum (1,k - 1)   = (dp[i - 1][k]   - sum(1,k)) + sum (1,j) 
    而 dp[i -1][k] - sum(1,k - 1)  相对于 dp[i][j]  来说 是 以知的   所以    
    dp[i -1][k] - sum(1,k - 1)      就是  我们 队列 要维护的状态

    右边同理 可得

      1 #include<stdio.h>
      2 #include<iostream>
      3 #include<algorithm>
      4 #include<cstring>
      5 #include<cmath>
      6 #include<queue>
      7 #include<set>
      8 #include<list>
      9 #include<map>
     10 #define Min(a,b)  a>b?b:a
     11 #define Max(a,b)  a>b?a:b
     12 #define CL(a,num)  memset(a,num,sizeof(a));
     13 #define inf 99999999
     14 #define maxn    10010
     15 #define mod 100000007
     16 #define eps  1e-6
     17 #define ll  long long
     18 #define M   15520
     19 using namespace std;
     20 int n,m,x,t;
     21 struct node
     22 {
     23     int x;
     24     int w;
     25     node(int xx,int yy): x(xx),w(yy){}
     26 };
     27 int f[110][maxn],sum[maxn] ,dp[110][maxn];
     28 int main()
     29 {
     30     //freopen("data.txt","r",stdin);
     31     int i ,j ;
     32     while(scanf("%d%d%d%d",&n,&m,&x,&t)!=EOF)
     33     {
     34         list<node>que;
     35         for(i = 0; i < n ;++i)
     36         {
     37             for(j = 1 ;j <= m; ++j)
     38             scanf("%d",&f[i][j]);
     39         }
     40 
     41         for(i = 0; i <= n;++i)
     42         {
     43             for( j = 0; j <= m ;++j)
     44             {
     45                 dp[i][j] = -inf ;
     46             }
     47         }
     48          int cnt = f[0][x];
     49          dp[0][x] = f[0][x] ;
     50         for(i = 0,j = x - 1; i < t&& j >=1;i++,j--)//往左处理
     51         {   cnt += f[0][j];
     52             dp[0][j] = cnt ;
     53         }
     54 
     55         cnt = f[0][x] ;
     56         for(i = 0,j = x + 1; i < t && j <= m;i++,j++)// 往右处理
     57         {
     58            cnt += f[0][j] ;
     59            dp[0][j] = cnt ;
     60 
     61 
     62         }
     63 
     64         for(i = 1; i < n;++i)
     65         {
     66             sum[0] = 0;
     67             que.clear() ;//  注意要清空  我就 WA 一次
     68             for(j = 1 ; j <= m ;++j)//左处理
     69             {
     70 
     71 
     72 
     73                 sum[j] = sum[j - 1] + f[i][j] ;
     74 
     75                 while(!que.empty() && que.front().x < j - t)   //距离 大于 t 了 要出队列
     76                    que.pop_front();
     77 
     78                    int  tmp = dp[i - 1][j] - sum[j - 1] ;
     79 
     80                 while(!que.empty() && que.back().w  <= tmp)
     81                      que.pop_back() ;
     82 
     83                  que.push_back(node(j,tmp));
     84                 if(!que.empty())
     85                     dp[i][j] =  sum[j] + que.front().w  ;
     86 
     87             }
     88 
     89 
     90 
     91 
     92 
     93             que.clear() ;
     94             sum[m + 1] = 0;
     95             for(j = m ; j >= 1 ;--j)//  右处理
     96             {
     97 
     98 
     99                 sum[j] = sum[j + 1] + f[i][j] ;
    100 
    101                 while(!que.empty() && que.front().x - j  > t)//距离 大于 t 了 要出队列
    102                    que.pop_front();
    103 
    104                    int  tmp = dp[i - 1][j] - sum[j + 1] ;
    105 
    106                 while(!que.empty() && que.back().w  <= tmp)
    107                      que.pop_back() ;
    108 
    109                  que.push_back(node(j,tmp));
    110 
    111                 if(!que.empty())
    112                     dp[i][j] = max(dp[i][j],sum[j] + que.front().w );
    113                     
    114             }
    115 
    116 
    117      }
    118 
    119        int ans = dp[n - 1][1];
    120         for(i = 2;i <= m;++i)
    121         {
    122             ans = max(ans,dp[n - 1][i]);
    123         }
    124         printf("%d\n",ans);
    125 
    126 
    127 
    128     }
    129 }

     

       

     

     
  • 相关阅读:
    AJAX问题总结(针对JAVA)
    关于IE浏览器的缓存问题
    tomcat和jdk版本兼容问题。
    Java中的索引和数据库的索引区别
    Eclipse 连接Oracle 11g 时报ORA-12505错误的解决办法
    Tomcat 8 & JNDI Datasource
    【LeetCode】019. Remove Nth Node From End of List
    【前端UI框架】EasyUI
    装饰者模式
    【LeetCode】234. Palindrome Linked List
  • 原文地址:https://www.cnblogs.com/acSzz/p/2644370.html
Copyright © 2011-2022 走看看