洛谷P1879 [USACO06NOV]玉米田Corn Fields

P1879 [USACO06NOV]玉米田Corn Fields

看到 N 较小 , 应该能想到 状态压缩

  • 状态设计

F[I][J]

表示第I行处于状态J,总的方案数 ;

那么容易得出F[I][J] =  F [ i ] [ j ] = s u m ( F [ i − 1 ] [ 0 ] , F [ i − 1 ] [ 1 ] , F [ i − 1 ] [ 2 ] ) F[i][j]=sum(F[i-1][0],F[i-1][1],F[i-1][2]) F[i][j]=sum(F[i1][0],F[i1][1],F[i1][2])

  • 判断状态是否合法

    (i<<1)&i
    

    这可以判断I中是否有相邻的两个1;

  • 调试的小技巧

    显示数字代表的状态

    string Dbg(int X) {
        string Ans = "" ;
        for (R int i = 0 ; i < M ; ++ i) {
            Ans = (char)('0' + (((1<<i)&X)?1:0)) + Ans ;
        }
        return Ans ;
    }
    
  • Code

    #include 
    #include 
    #define re register
    #define gc getchar()
    int Qread () {
        int x = 0,f = 1;
        char ch = gc ;
        while (ch >'9' || ch < '0') {
            if (ch =='-')f = -1;
            ch = gc ;
        }
        while (ch >='0' && ch <='9') {
            x = x * 10 + ch -'0' ;
            ch = gc ;
        }
        return x *f ;
    }
    const int Wzx = 100000000 ;
    int N , M ,F[14][4098];
    unsigned short int A[14] , Pw;
    int main () {
        //freopen ("P1879.in" , "r" , stdin) ;
        N = Qread () , M = Qread () ;
        Pw = 1 << M ;
        memset (A , 0 ,sizeof (A)) ;
        re unsigned int i , j , k;
        for (i = 0; i < N; ++ i) {
            for (j = 0 ; j < M ; ++ j) {
                A[i]= A[i] | (Qread() << j) ;
            }
            A[i] = ~A[i] ;
        }
        memset (F , 0 , sizeof (F)) ;
        for (i = 0 ; i < Pw ; ++ i) {
            if ((i >> 1) & i) continue ;
            if (i&A[0]) continue ;
            F[0][i] = 1 ;
        }
        for (i = 1; i < N ; ++ i) {
            for (j = 0 ; j < Pw; ++ j) {
                if ((j>>1) & j) continue ;
                if (j&A[i]) continue ;
                for (k = 0 ; k < Pw ; ++ k) {
                    if (k&A[i-1]) continue ;
                    if (k&j)continue ;
                    F[i][j] += F[i-1][k] ;
                    F[i][j] %= Wzx; 
                }
            }
        }
        int Ans = 0 ;
        for (i = 0 ; i < Pw ; ++ i) {
            Ans += F[N-1][i] ;
            Ans %= Wzx; 
        }
        printf ("%d\n" , Ans) ;
        fclose (stdin) ;
        fclose (stdout);
        return 0;
    }
    

Thanks!

你可能感兴趣的:(DP)