【题目链接】
【算法】
和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 ",ans); return 0; }