• bzoj 2011


    决策单调性,对于一个1D/1D(状态是一维,转移也是一维)的DP,如果DP的决策具有单调性,那么就可以做到O(nlogn)的复杂度完成DP。

    感谢《1D/1D  动态规划优化初步》的作者。

     1 /**************************************************************
     2     Problem: 2216
     3     User: idy002
     4     Language: C++
     5     Result: Accepted
     6     Time:4916 ms
     7     Memory:14476 kb
     8 ****************************************************************/
     9  
    10 #include <cstdio>
    11 #include <algorithm>
    12 #include <cmath>
    13 #define N 500010
    14 using namespace std;
    15  
    16 struct Trid {
    17     int p, l, r;
    18     Trid(){}
    19     Trid( int p, int l, int r ):p(p),l(l),r(r){}
    20 };
    21  
    22 int n;
    23 int aa[N];
    24 int f[N], g[N], h[N];
    25 Trid stk[N]; int top;
    26  
    27 double calc( int j, int i ) {
    28     return aa[j]-aa[i]+sqrt(abs(i-j));
    29 }
    30 void dodp( int dp[N] ) {
    31     stk[top=1] = Trid(1,1,n);
    32     for( int i=2; i<n; i++ ) {
    33         if( calc(stk[top].p,n)>calc(i,n) ) continue;
    34          
    35         while( stk[top].l>=i && 
    36                 calc(stk[top].p,stk[top].l)<calc(i,stk[top].l) )
    37             top--;
    38         if( stk[top].r==i-1 ) {
    39             stk[++top] = Trid( i, i, n );
    40         } else {
    41             int lf = max( stk[top].l+1, i );
    42             int rg = min( stk[top].r+1, n );
    43             int p = stk[top].p;
    44             while( lf<rg ) {
    45                 int mid=(lf+rg)>>1;
    46                 if( calc(p,mid) > calc(i,mid) ) lf=mid+1;
    47                 else rg=mid;
    48             }
    49             stk[top].r = lf-1;
    50             stk[++top] = Trid( i, lf, n );
    51         }
    52     }
    53     for( int i=1; i<=top; i++ ) 
    54         for( int j=stk[i].l; j<=stk[i].r; j++ )
    55             dp[j] = stk[i].p;
    56 }
    57 int main() {
    58     scanf( "%d", &n );
    59     for( int i=1; i<=n; i++ )
    60         scanf( "%d", aa+i );
    61     dodp(f);
    62     reverse( aa+1, aa+1+n );
    63     dodp(g);
    64     reverse( aa+1, aa+1+n );
    65  
    66     for( int i=1; i<=n; i++ ) 
    67         g[i] = n+1-g[i];
    68     reverse( g+1, g+1+n );
    69  
    70     for( int i=1; i<=n; i++ )
    71         if( calc(f[i],i)>calc(g[i],i) ) h[i]=f[i];
    72         else h[i]=g[i];
    73     for( int i=1; i<=n; i++ )
    74         printf( "%lld
    ", (long long)ceil(calc(h[i],i)) );
    75 }
    View Code
  • 相关阅读:
    Java IO流
    Java中Char和Byte的区别
    Java常用类
    View
    3 View
    View
    3 View
    3 View视图 URLconf
    2 Model层
    2 Model层-模型成员
  • 原文地址:https://www.cnblogs.com/idy002/p/4402818.html
Copyright © 2020-2023  润新知