1.違法なステータスの判断に注意を払う
2.バイナリを使用して、最初にすべての状態を取得します
3.次に、それが合法であるかどうかを判断します。合法である場合は、転送に保存します。
#include <iostream>
#include <vector>
#include <string.h>
#include <algorithm>
#include <stdio.h>
#define int long long
using namespace std;
const int N = 12, M = 1 << 10, K = 110;
int n,m;
vector<int> state;
int id[M],cnt[M];
vector<int> head[M];
int f[N][K][M];
//检查是否合法
//如果连着两个状态都是1,那必然不合法
bool check(int state)
{
for (int i=0;i<n;i++)
if((state >> i & 1) && (state >> (i + 1) & 1))
return false;
return true;
}
//统计1的个数
int count(int state)
{
int res = 0;
for(int i=0;i<n;i++) res += state >> i & 1;
return res;
}
signed main() {
cin>>n>>m;
for(int i=0;i < 1 << n;i++)
{
// 如果合法
if(check(i)){
state.push_back(i);
// 记录一下位置
id[i] = state.size() - 1;
// 记录一下用了几个
cnt[i] = count(i);
}
}
// 然后就开始连状态变化了
for(int i=0;i<state.size();i ++)
for(int j=0;j<state.size();j++)
{
int a = state[i];int b = state[j];
if((a & b) == 0 && check(a | b)){
head[i].push_back(j);
}
}
f[0][0][0]=1;
for(int i=1;i<=n+1;i++)
for(int j=0;j<=m;j++)
for(int a = 0;a < state.size();a++)
for(int b : head[a]){
int c = cnt[state[a]];
if(j>=c){
f[i][j][a] += f[i-1][j-c][b];
}
}
cout<<f[n+1][m][0]<<endl;
}