美文网首页信息学竞赛题解(IO题解)
BZOJ-1499: [NOI2005]瑰丽华尔兹(DP+单调队

BZOJ-1499: [NOI2005]瑰丽华尔兹(DP+单调队

作者: AmadeusChan | 来源:发表于2018-10-17 12:06 被阅读0次

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1499

    可以很容易的写出DP方程f[t][i][j]=max(f[t-1][i][j],f[t-1][last(i)][last(j)]+1),但是这个DP的总复杂度是O(nmT),会TLE,所以不用时间来划分状态,而是使用时段来划分状态,h表示第h个时间段,那么f[h][i][j]=max(f[h-1][last(i)][last(j)]+dist(i,j,last(i),last(j))),这个方程直接转移状态是O(n),但是我们可以使用单调队列优化维护决策到O(1),那么DP复杂度就成了O(nmk),可以AC。

    代码:

    #include <cstdio>
    
    #include <algorithm>
    
    #include <cstring>
    
    #include <deque>
    
     
    
    using namespace std ;
    
     
    
    #define MAXN 210
    
    #define MAXK 210
    
    #define rep( i , x )for(int i =0; i ++< x ;)
    
    #define dow( i , x )for(int i = x ; i ;-- i )
    
     
    
    char map[ MAXN ][ MAXN ];
    
    int f[ MAXN ][ MAXN ][ MAXN ], n , m , k , x , y ;
    
     
    
    deque <int> Q ;
    
     
    
    int main(  ){
    
        scanf("%d%d%d%d%d",&n ,&m ,&x ,&y ,&k );
    
        rep( i , n )scanf("%s", map[ i ]+1);
    
        rep( i , n )rep( j , m ) f[0][ i ][ j ]=-1;
    
        f[0][ x ][ y ]=0;
    
        rep( h , k ){
    
            int l , r , d ;scanf("%d%d%d",&l ,&r ,&d );
    
            rep( i , n )rep( j , m ) f[ h ][ i ][ j ]=-1;
    
            if( d ==1){
    
                rep( j , m ){
    
                    Q.clear(  );
    
                    dow( i , n )if( map[ i ][ j ]=='.'){
    
                        while(! Q.empty(  )&& Q.front(  )- i > r - l +1) Q.pop_front(  );
    
                        if( f[ h -1][ i ][ j ]!=-1){
    
                            while(! Q.empty(  )&& Q.back(  )- i + f[ h -1][ Q.back(  )][ j ]<= f[ h -1][ i ][ j ]) Q.pop_back(  );
    
                            Q.push_back( i );
    
                        }
    
                        if(! Q.empty(  )) f[ h ][ i ][ j ]= f[ h -1][ Q.front(  )][ j ]+ Q.front(  )- i ;
    
                        else f[ h ][ i ][ j ]=-1;
    
                    }else{
    
                        Q.clear(  ); f[ h ][ i ][ j ]=-1;
    
                    }
    
                }
    
            }else if( d ==2){
    
                rep( j , m ){
    
                    Q.clear(  );
    
                    rep( i , n )if( map[ i ][ j ]=='.'){
    
                        while(! Q.empty(  )&& i - Q.front(  )> r - l +1) Q.pop_front(  );
    
                        if( f[ h -1][ i ][ j ]!=-1){
    
                            while(! Q.empty(  )&& i - Q.back(  )+ f[ h -1][ Q.back(  )][ j ]<= f[ h -1][ i ][ j ]) Q.pop_back(  );
    
                            Q.push_back( i );
    
                        }
    
                        if(! Q.empty(  )) f[ h ][ i ][ j ]= f[ h -1][ Q.front(  )][ j ]+ i - Q.front(  );
    
                        else f[ h ][ i ][ j ]=-1;
    
                    }else{
    
                        Q.clear(  ); f[ h ][ i ][ j ]=-1;
    
                    }
    
                }
    
            }else if( d ==3){
    
                rep( i , n ){
    
                    Q.clear(  );
    
                    dow( j , m )if( map[ i ][ j ]=='.'){
    
                        while(! Q.empty(  )&& Q.front(  )- j > r - l +1) Q.pop_front(  );
    
                        if( f[ h -1][ i ][ j ]!=-1){
    
                            while(! Q.empty(  )&& Q.back(  )- j + f[ h -1][ i ][ Q.back(  )]<= f[ h -1][ i ][ j ]) Q.pop_back(  );
    
                            Q.push_back( j );
    
                        }
    
                        if(! Q.empty(  )) f[ h ][ i ][ j ]= Q.front(  )- j + f[ h -1][ i ][ Q.front(  )];
    
                        else f[ h ][ i ][ j ]=-1;
    
                    }else{
    
                        Q.clear(  ); f[ h ][ i ][ j ]=-1;
    
                    }
    
                }
    
            }else{
    
                rep( i , n ){
    
                    Q.clear(  );
    
                    rep( j , m )if( map[ i ][ j ]=='.'){
    
                        while(! Q.empty(  )&& j - Q.front(  )> r - l +1) Q.pop_front(  );
    
                        if( f[ h -1][ i ][ j ]!=-1){
    
                            while(! Q.empty(  )&& j - Q.back(  )+ f[ h -1][ i ][ Q.back(  )]<= f[ h -1][ i ][ j ]) Q.pop_back(  );
    
                            Q.push_back( j );
    
                        }
    
                        if(! Q.empty(  )) f[ h ][ i ][ j ]= j - Q.front(  )+ f[ h -1][ i ][ Q.front(  )];
    
                        else f[ h ][ i ][ j ]=-1;
    
                    }else{
    
                        Q.clear(  ); f[ h ][ i ][ j ]=-1;
    
                    }
    
                }
    
            }
    
        }
    
        int ans =0;
    
        rep( i , n )rep( j , m ) ans =max( ans , f[ k ][ i ][ j ]);
    
        printf("%d\n", ans );
    
        return 0;
    
    }
    

    相关文章

      网友评论

        本文标题:BZOJ-1499: [NOI2005]瑰丽华尔兹(DP+单调队

        本文链接:https://www.haomeiwen.com/subject/mrglzftx.html