BZOJ-1801: [Ahoi2009]chess 中国象棋(

作者: AmadeusChan | 来源:发表于2019-03-13 12:55 被阅读0次

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

    动态规划,dp(i,j,k)表示前i行有j列一个炮,k列两个炮,然后弄点组合的内容DP一下就好了。

    代码(WA了N次之后改LL就A了。。。):

    #include <cstdio>
    
    #include <algorithm>
    
    #include <cstring>
    
     
    
    using namespace std ;
    
     
    
    #define REP( i , l , r ) for ( int i = l ; i <= r ; ++ i )
    
     
    
    typedef long long ll ;
    
     
    
    const ll maxn = 110 , mod = 9999973 ;
    
     
    
    ll dp[ maxn ][ maxn ][ maxn ] , n , m , ans = 0 ;
    
     
    
    inline void add( ll i , ll j , ll k , ll v ) {
    
        if ( i > 0 && i <= n && j >= 0 && k >= 0 && j + k <= m ) {
    
            ( dp[ i ][ j ][ k ] += v ) %= mod ;
    
        }
    
    }
    
     
    
    inline ll C( ll x ) {
    
        return ( ( x * ( x - 1 ) ) / 2 ) % mod ;
    
    }
    
     
    
    inline ll M( ll x , ll y ) {
    
        return ( x * y ) % mod ;
    
    }
    
     
    
    int main(  ) {
    
        memset( dp , 0 , sizeof( dp ) ) ;
    
        scanf( "%lld%lld" , &n , &m ) ;
    
        dp[ 0 ][ 0 ][ 0 ] = 1 ;
    
        REP( i , 0 , ( n - 1 ) ) REP( j , 0 , m ) REP( k , 0 , m ) if ( dp[ i ][ j ][ k ] ) {
    
            ll c = dp[ i ][ j ][ k ] ;
    
            add( i + 1 , j , k , c ) ;
    
            add( i + 1 , j + 1 , k , c * ( m - j - k ) ) ;
    
            add( i + 1 , j - 1 , k + 1 , c * j ) ;
    
            add( i + 1 , j + 2 , k , c * C( m - j - k ) ) ;
    
            add( i + 1 , j - 2 , k + 2 , c * C( j ) ) ;
    
            add( i + 1 , j , k + 1 , c * M( m - j - k , j ) ) ;
    
        }
    
        REP( j , 0 , m ) REP( k , 0 , ( m - j ) ) ( ans += dp[ n ][ j ][ k ] ) %= mod ;
    
        printf( "%lld\n" , ans ) ;
    
        return 0 ;
    
    }
    

    相关文章

      网友评论

        本文标题:BZOJ-1801: [Ahoi2009]chess 中国象棋(

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