您的位置:首页 > 其它

[luoguP1879] [USACO06NOV]玉米田Corn Fields(DP)

2017-05-30 19:34 162 查看

传送门

 

说要统计方案,感觉就是个 Σ

而矩阵中只有 01 ,可以用二进制表示

这样,预处理出每一个每一行所有可能的状态 s

然后初始化第一行所有状态的方案数为 1

f[i][j] = Σf[i - 1][k] (k 和 j 不冲突,j 为第 i 行所有方案,k 为第 i - 1 行所有方案)

 

——代码

#include <cstdio>
#include <iostream>
#define mod 100000000

int n, m, ans;
int f[13][1 << 13], pos[13][1 << 13], s[13][1 << 13];

inline int read()
{
int x = 0, f = 1;
char ch = getchar();
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0';
return x * f;
}

inline void dfs(int k, int i, int num)
{
if(i > pos[k][0])
{
s[k][++s[k][0]] = num;
return;
}
dfs(k, i + 1, num);
if((pos[k][i] ^ (pos[k][i - 1] + 1)) || (i == 1))
dfs(k, i + 1, num + (1 << pos[k][i] - 1));
else if((i ^ 1) && (pos[k][i] == pos[k][i - 1] + 1))
if(((num >> pos[k][i - 1] - 1) & 1) ^ 1)
dfs(k, i + 1, num + (1 << pos[k][i] - 1));
}

int main()
{
int i, j, k, x;
n = read();
m = read();
for(i = 1; i <= n; i++)
for(j = 1; j <= m; j++)
{
x = read();
if(x) pos[i][++pos[i][0]] = j;
}
for(i = 1; i <= n; i++) dfs(i, 1, 0);
for(i = 1; i <= s[1][0]; i++) f[1][i] = 1;
for(i = 2; i <= n; i++)
for(j = 1; j <= s[i][0]; j++)
for(k = 1; k <= s[i - 1][0]; k++)
if(!(s[i][j] & s[i - 1][k]))
{
f[i][j] += f[i - 1][k];
if(f[i][j] >= mod) f[i][j] -= mod;
}
for(i = 1; i <= s
[0]; i++)
{
ans += f
[i];
if(ans >= mod) ans -= mod;
}
printf("%d\n", ans);
return 0;
}
View Code

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: