题目描述
在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案。国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子。
注:数据有加强(2018/4/25)
输入格式
只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N)
输出格式
所得的方案数
输入输出样例
输入 #1
3 2
输出 #1
16
题目来源洛谷P1896/四川省选
有点像八皇后 但是看数据范围应该可以用状压dp
上代码
#include<iostream> #include<cstdio> using namespace std; long long n,k,dp[15][2050][205],sc[2050],num[2050]; long long ans,cnt; long long getnum(long long x) { long long res=0; while(x)res+=(x&1),x>>=1; return num[(int)cnt]=res; } int main() { scanf("%lld%lld",&n,&k); long long maxn=(1<<n)-1; for(long long i=0;i<=maxn;i++) if(!(i&(i<<1)))sc[++cnt]=i,dp[1][cnt][getnum(i)]=1; for(long long i=2;i<=n;i++) { for(long long j=1;j<=cnt;j++) { for(long long l=1;l<=cnt;l++) { long long x=sc[j],y=sc[l]; if(x&y)continue; if(x&(y<<1))continue; if(x&(y>>1))continue; for(long long m=0;m<=k;m++)dp[i][j][m+num[j]]+=dp[i-1][l][m]; } } } for(long long i=1;i<=cnt;i++)ans+=dp[n][i][k]; printf("%lld",ans); return 0; }