玉米田 状压dp
Posted 行码棋
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了玉米田 状压dp相关的知识,希望对你有一定的参考价值。
和【国王】那题一样的套路
用一个数记录该行的状态,还要记录能够互相转移的状态
满足题意需要:
- 不能出现连续的两个1
- 两个数的与运算必须为0,这样才能转移
处理不育的玉米田,把不育的玉米田也转化为一个状态,将目标的状态和不育玉米田的状态做与运算,当结果大于0时,说明玉米放在了不育的玉米田上,需要舍弃这种情况。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 14,M = 1<<12,mod = 1e8;
int n,m;
vector<int>state;
vector<int>head[M];
int f[N][M],g[N];
//检查状态是否有连续的1
bool check(int x)
{
for(int i=0;i<=m;i++)
if((x>>i&1) && (x>>i+1)&1)
return false;
return true;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=0;j<m;j++)
{
int a;cin>>a;
g[i] += !a << j;
}
for(int i=0;i< 1<<m;i++)
if(check(i))
state.push_back(i);
for(int i=0;i<state.size();i++)
for(int j=0;j<state.size();j++)
{
int a = state[i],b = state[j];
if((a&b)==0)
head[i].push_back(j);
}
f[0][0] = 1;
for(int i=1;i<=n+1;i++)
for(int j=0;j<state.size();j++)
{
if(g[i]&state[j]) continue;
for(int b : head[j])
{
f[i][j] = (f[i][j] + f[i-1][b])%mod;
}
}
cout<<f[n+1][0]<<'\\n';
return 0;
}
以上是关于玉米田 状压dp的主要内容,如果未能解决你的问题,请参考以下文章
[USACO06NOV]玉米田Corn Fields (状压$dp$)
状压DP水题[USACO06NOV]玉米田Corn Fields
P1879 [USACO06NOV]玉米田Corn Fields 状压dp
[USACO06NOV]玉米田$Corn Fields$ (状压$DP$)
ybtoj 状压DP课堂过关 例题1jzoj 1266 luogu P1879 [USACO06NOV]Corn Fields G & 玉米田 & 种植方案