Segment tree optimization dp (elect selection)

Several days before the exams, but now I think of it tune. .

The meaning of problems

Selected from the lattice, the selected minimum weight requirements, but each selected grid range is limited: abs (jk) <= w [i] [j] + w [i-1] [k] w which is another value

暴力:O(n*m*m*T)

Optimization : For the grid line to be selected, the range over which the row of the grid to cover out process, and then select the row, resulting in the desired rapid grid which can be selected from a range, a minimum weight cell

Then for each line segment tree with a minimum maintenance, to put the next line segment tree emptying, re-modify

#include<bits/stdc++.h>
using namespace std;
#define mid ((l+r)>>1)
#define N 105
#define M 5005
#define inf 0x7f7f7f
int a[N][M],dp[N][M],minn[M*4],fl[M*4],l[N][M],r[N][M];
void update(int s)
{ minn[s]=min(minn[s<<1],minn[s<<1|1]); }
void pushdown(int s)
{
    if(fl[s]==inf) return ;
    minn[s<<1] = min (a [i << 1 ], in [i]); 
    in [s << 1 ] = min (in [s << 1 ], in [i]); 
    from [the << 1 | 1 ] = min (a [i << 1 | 1 ], in [i]); 
    in [the << 1 | 1 ] = min (in [s << 1 | 1 ], in [i]); 
    in [s] = inf; 
} 
Void build ( you 's, you're with, you r) 
{ 
    at [s] = inf;
    ow (l == r) {a [i] = inf;  return ;} 
    Build (S << . 1 , L, MID); Build (<< S . 1 | . 1 , MID + . 1 , R & lt); 
    Update (S); 
} 
void Modify ( int S, int L, int R & lt, int L , int R & lt, int V) 
{ 
    IF (L <= R & lt && L <= R & lt) { 
        Minn [S] = min (Minn [S], V); // be sure to remember to update! ! 
        FL [S] = min (FL [S], V);
         return ; 
    } 
    pushdown (S); // Modify query and downstream are marked 
    if(L<=mid) modify(s<<1,l,mid,L,R,v);
    if(R>mid)  modify(s<<1|1,mid+1,r,L,R,v);
    update(s);
}
int query(int s,int l,int r,int L,int R)
{
    if(L<=l&&r<=R) return minn[s];
    pushdown(s);
    int ans=inf;
    if(L<=mid) ans=min(ans,query(s<<1,l,mid,L,R));
    if(R>mid)  ans=min(ans,query(s<<1|1,mid+1,r,L,R));
    return ans;
}
int main()
{
    freopen("elect.in","r",stdin);
    freopen("elect.out","w",stdout);
    int T,n,m;
    scanf("%d%d%d",&T,&n,&m);
    while(T--){
        int ans=0x7f7f7f;
        for(int i=1;i<=n;i++)
          For ( int J = . 1 ; J <= m; J ++ ) 
          Scanf ( " % D " , & A [I] [J]);
         for ( int I = . 1 ; I <= n-; I ++ )
          for ( int J = . 1 ; J <= m; J ++ ) {
              int X; 
             Scanf ( " % D " , & X); 
             L [I] [J] = max ( . 1 , JX); // for each point of each line is obtained to cover the maximum distance interval to maintain the value of the most segment tree with 
             R & lt [I] [J] = min (m, J +  X);
         }
        build(1,1,m);
        for(int i=1;i<=m;i++)
         dp[1][i]=a[1][i],modify(1,1,m,l[1][i],r[1][i],dp[1][i]);
        for(int i=2;i<=n;i++){
             for(int j=1;j<=m;j++)
               dp[i][j]=query(1,1, m, L [I] [J], R & lt [I] [J]) + A [I] [J]; 
             Build ( . 1 , . 1 , m); // row corresponding to a segment tree! ! Line after use to rebuild 
             for ( int J = . 1 ; J <= m; J ++ ) 
             Modify ( . 1 , . 1 , m, L [I] [J], R & lt [I] [J], DP [I] [J ]); 
        } 
        for ( int I = . 1 ; I <= m; I ++) ANS = min (ANS, DP [n-] [I]); 
        the printf ( " % D \ n- " , ANS); 
    } 
} 
/ * 
. 1 
. 3. 5 
. 9. 8. 7. 3. 5 
. 8. 9 2. 8. 6 
. 1. 9. 7. 8. 6 

0 0. 1. 1 2 
. 1. 1. 1 0 2 
0 2. 1 0 2 
* /

 

Guess you like

Origin www.cnblogs.com/mowanying/p/11222832.html