#include <bits/stdc++.h>
using namespace std;
const int N = 1 << 10 + 5;
int n, k, init[N], cnt, _1cnt[N], s1, s2;//init单行合法的所有状态 _1cnt[x]x的二进制中1的个数
long long f[11][N][100], ans;//f[x][s][y] 用y个国王,第x行放状态s的放法
inline int get1cnt(int i)
{
int res = 0;
while(i)
{
res += i & 1;
i >>= 1;
}
return res;
}
void optbin(int i)//倒序输出树,debug用
{
while(i)
{
printf("%d", i & 1);
i >>= 1;
}
printf("\n");
}
inline bool check_singleline(const int &i)
{
//return !((i & (i >> 1)) || (i & (i << 1)));
return !(i & ((i >> 1) | (i << 1)));
}
inline bool check(const int &i, const int &j)
{
//return !((i & j) || ((i << 1) & j) || ((i >> 1) & j));
return !((j | (j << 1) | (j >> 1)) & i);
}
int main()
{
scanf("%d %d", &n, &k);
//for(int x = 0; x <= (1 << n + 1) - 1; x++)
for(int x = 0; x < (1 << n); x++)
{
_1cnt[x] = get1cnt(x);
//optbin(x);
if(check_singleline(x)) init[++cnt] = x;
}
f[0][0][0] = 1;
for(int x = 1; x <= n; x++)
{
for(int s1_ = 1; s1_ <= cnt; s1_++)
{
s1 = init[s1_];
for(int s2_ = 1; s2_ <= cnt; s2_++)
{
s2 = init[s2_];
/*printf("check{\n");
optbin(s1);
optbin(s2);
printf("} = %d\n", check(s1, s2));*/
if(check(s1, s2)) for(int y = 0; y <= k; y++) if(y >= _1cnt[s1]) f[x][s1][y] += f[x - 1][s2][y - _1cnt[s1]];//, printf("f[%d][%d][%d] = %d-%d\n", x, s1, y, f[x][s1][y], x == n && y == k);
}
}
}
for(int x = 1; x <= cnt; x++) ans += f[n][init[x]][k];//, printf("ans+=f[%d][%d][%d] %d=%d\n", n, init[x], k, f[n][init[x]][k], ans);
printf("%lld", ans);
return 0;
}
样例输出16