【题目链接】
【算法】
和HDU2167类似
先搜出一行内符合的状态,然后,f[i][j][k]表示第i行,第j种状态,放了k个,合法的方案,DP即可
【代码】
#include<bits/stdc++.h>
using namespace std;
#define MAXN 10
#define MAXK 85
const int MAXS = 1024;
int i,j,x,y,tot,n,k,tmp,MASK;
long long f[MAXN][MAXS][MAXK];
long long ans;
struct info
{
int x,s;
} ST[MAXS];
int calc(int s)
{
int i,ret = 0;
for (i = 0; i < n; i++)
{
if (s & (1 << i))
ret++;
}
return ret;
}
int main()
{
scanf("%d%d",&n,&k);
MASK = (1 << n) - 1;
for (i = 0; i <= MASK; i++)
{
if (i & (i << 1)) continue;
tmp = calc(i);
if (tmp <= k) ST[++tot] = (info){i,tmp};
f[1][tot][tmp] = 1;
}
for (i = 2; i <= n; i++)
{
for (j = 1; j <= tot; j++)
{
for (x = ST[j].s; x <= k; x++)
{
for (y = 1; y <= tot; y++)
{
if (ST[j].x & ST[y].x) continue;
if (ST[j].x & (ST[y].x << 1)) continue;
if (ST[j].x & (ST[y].x >> 1)) continue;
f[i][j][x] += f[i-1][y][x - ST[j].s];
}
}
}
}
for (i = 1; i <= tot; i++) ans += f[n][i][k];
printf("%lld\n",ans);
return 0;
}