ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

洛谷P1879 [USACO06NOV]玉米田Corn Fields(状压dp)

2019-08-15 19:54:09  阅读:331  来源: 互联网

标签:玉米田 洛谷 int Fields Corn 状压 USACO06NOV


\(f[i][j]\) 表示前 \(i\) 行且第 \(i\) 行状态为 \(j\) 的方案总数。\(j\) 的大小为 \(0 \to (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\n", ans);
    return 0;
}

标签:玉米田,洛谷,int,Fields,Corn,状压,USACO06NOV
来源: https://www.cnblogs.com/solvit/p/11360135.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有