首页 > 代码库 > poj 3254

poj 3254

状态压缩 dp

dp[i][j] 为第 i 行状态为 j 的总数

#include <cstdio>#include <cstdlib>#include <cmath>#include <map>#include <set>#include <queue>#include <stack>#include <vector>#include <sstream>#include <string>#include <cstring>#include <algorithm>#include <iostream>#define maxn 2005#define INF 0x3f3f3f3f#define inf 10000000#define MOD 100000000#define ULL unsigned long long#define LL long longusing namespace std;int dp[15][1 << 13], mapp[1 << 13], sta[1 << 13];int n, m, num;void init() {    memset(dp, 0, sizeof(dp));    memset(mapp, 0, sizeof(mapp));    num = 0;    for(int i = 0; i < (1<<m); ++ i) {        int d = i&(i << 1);        if(d == 0) sta[num++] = i;    }    // printf("num : %d\n", num);}int main(){    while(scanf("%d%d", &n, &m) == 2) {        init();        // puts("*********************");        // for(int i = 0; i < num; ++ i) {        //     printf("%d ", sta[i]);        // }        // puts("**********************");        for(int i = 0; i < n; ++ i) {            for(int j = 0; j < m; ++ j) {                int a;                scanf("%d", &a);                if(a == 0) mapp[i] = mapp[i]|(1 << j);            }        }        for(int i = 0; i < num; ++ i) {            if((mapp[0] & sta[i]) == 0) {                dp[0][i] = 1;            }        }        for(int i = 1; i < n; ++ i) {            for(int j = 0; j < num; ++ j) {                if(mapp[i-1] & sta[j]) continue;                for(int q = 0; q < num; ++ q) {                    if(mapp[i]&sta[q] || sta[j]&sta[q]) continue;                    dp[i][q] += dp[i-1][j];                    dp[i][q] %= MOD;                }            }        }        int ans = 0;        for(int i = 0; i < num; ++ i) {            ans += dp[n-1][i];            ans %= MOD;        }         printf("%d\n", ans);    }    return 0;}