算法提高之玉米田
-
核心思想:状态压缩dp
- 将图存入g数组 存的时候01交换一下方便后面判断
- 即g数组中0为可以放的地方 state中1为放的地方 这样只要state为1 g为0就可以判断不合法
-
#include <iostream> #include <cstring> #include <algorithm> #include <vector> using namespace std; const int N = 14,M = 1<<N,mod = 1e8; int f[N][M]; int n,m,k; int g[N]; vector<int> states; vector<int> head[M]; bool check(int state) { return !(state & state<<1); //左右不能有相邻1 } int main() { cin>>n>>m; for(int i=1;i<=n;i++) for(int j=0;j<m;j++) cin>>k,g[i] |= !k << j; //实际上倒过来了 影响的只有方案组成 数量不变 for(int st=0;st<1<<m;st++) if(check(st)) states.push_back(st); //存储合法图 for(auto st:states) for(auto ne_st:states) if(!(st & ne_st)) //找可以组合的两张图 head[st].push_back(ne_st); f[0][0] = 1; for(int i=1;i<=n+1;i++) for(auto st:states) if(!(st&g[i])) //若合法 更新f[i][st] for(auto pre_st:head[st]) f[i][st] = (f[i][st] + f[i-1][pre_st]) %mod; cout<<f[n+1][0]<<endl; return 0; }