【USACO 2006 November Gold】Corn Fields

【题目链接】

          点击打开链接

【算法】

         状压DP

【代码】

    

#include
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  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  inline void write(T x) {
	if (x < 0) { putchar('-'); x = -x; }
	if (x > 9) write(x/10);
	putchar(x%10+'0');	
}
template  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;
	
}

你可能感兴趣的:(动态规划)