【USACO 2006 November Gold】Corn Fields

【题目链接】

          点击打开链接

【算法】

         状压DP

【代码】

    

#include<bits/stdc++.h>
using namespace std;
#define MAXN 12
#define MOD 100000000

int M,N,i,j,k,ans,state;
int ST[MAXN+1][(1<<12)+1],f[MAXN+1][(1<<12)+1],cnt[MAXN+1],mat[MAXN+1][MAXN+1];

template <typename T> inline void read(T &x) {
    int f = 1; x = 0;
    char c = getchar();
    for (; !isdigit(c); c = getchar()) { if (c == '-') f = -f; }
    for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
    x *= f;
}
template <typename T> inline void write(T x) {
    if (x < 0) { putchar('-'); x = -x; }
    if (x > 9) write(x/10);
    putchar(x%10+'0');    
}
template <typename T> inline void writeln(T x) {
    write(x);
    puts("");    
}

inline void dfs(int dep) {
    if (dep > N) ST[i][++cnt[i]] = state;
    else {
        dfs(dep+1);
        if (mat[i][dep]) {
            if ((dep == 1) || (!(state & (1 << (N - dep + 1))))) {
                state |= (1 << (N - dep));
                dfs(dep+1);
                state &= (~(1 << (N - dep)));
            }
        }
    }
}

int main() {
    
    read(M); read(N);
    
    for (i = 1; i <= M; i++) {
        for (j = 1; j <= N; j++) {
            read(mat[i][j]); 
        } 
    }    
    
    for (i = 1; i <= M; i++) dfs(1);
    
    for (i = 1; i <= cnt[1]; i++) f[1][i] = 1;
    for (i = 2; i <= M; i++) {
        for (j = 1; j <= cnt[i]; j++) {
            for (k = 1; k <= cnt[i-1]; k++) {
                if (!(ST[i][j] & ST[i-1][k]))
                    f[i][j] = (f[i][j] + f[i-1][k]) % MOD;
            }
        }    
    }
    
    for (i = 1; i <= cnt[M]; i++) ans = (ans + f[M][i]) % MOD;
    writeln(ans);
    
    return 0;
    
}

 

posted @ 2018-02-12 18:10  evenbao  阅读(189)  评论(0编辑  收藏  举报