zoukankan      html  css  js  c++  java
  • 洛谷P1879 [USACO06NOV]玉米田Corn Fields(状压dp)

    洛谷P1879 [USACO06NOV]玉米田Corn Fields

    (f[i][j]) 表示前 (i) 行且第 (i) 行状态为 (j) 的方案总数。(j) 的大小为 (0 o (1 >> n - 1))

    (i) 行,种植状态为 (j) 的方案总数等于所有合法的 (f[i-1][k]) 之和。

    • 状态 (j) 满足同一行内没有相邻的两块草地(没有共同边)。
    • 状态 (j)(k) 满足相邻两行的种植情况没有两块草地有共同边。

    [f[i][j] = sum f[i-1][k] quad j,k is legal ]

    #include<bits/stdc++.h>
    
    using namespace std;
    
    const int maxn = 1 << 12;
    const int mod = 1e9;
    int f[15][maxn], state[maxn], M[15][15], bit[15];
    int n, m, ans;
    
    int main()
    {
        scanf("%d%d", &m, &n);
        for(int i = 1; i <= m; i++){
            for(int j = 1; j <= n; j++){
                scanf("%d", &M[i][j]);
                bit[i] = (bit[i] << 1) + M[i][j];
            }
        }
        for(int i = 0; i < (1 << n); i++){
            state[i] = (((i & (i << 1)) == 0) && ((i & (i >> 1)) == 0));
            // = 的优先级高于 &
        }
        f[0][0] = 1;
        for(int i = 1; i <= m; i++){
            for(int j = 0; j < (1 << n); j++){
                if(state[j] && ((j & bit[i]) == j)){
                    for(int k = 0; k < (1 << n); k++){
                        if((j & k) == 0) f[i][j] = (f[i][j] + f[i - 1][k]) % mod;
                    }
                }
            }
        }
        ans = 0;
        for(int i = 0; i < (1 << n); i++){
            ans = (ans + f[m][i]) % mod;
        }
        printf("%d
    ", ans);
        return 0;
    }
    
  • 相关阅读:
    fwt
    fft,ntt
    loj6077
    高维前缀和
    hihocoder 1496 寻找最大值
    HDU 5977 Garden of Eden
    扩展crt
    有标号的DAG计数I~IV
    BZOJ 3160 万径人踪灭
    Codeforces Round #524 (Div. 2) F
  • 原文地址:https://www.cnblogs.com/solvit/p/11360135.html
Copyright © 2011-2022 走看看