洛谷P1896 [SCOI2005]互不侵犯King
题目描述
在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案。国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子。
输入输出格式
输入格式:
只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N)
输出格式:
所得的方案数
输入输出样例
输入样例#1: 复制
3 2
输出样例#1: 复制
16
#include<iostream> #include<cstdio> using namespace std; int n,k,top=0; int c[1<<10],s[1<<10]; long long f[11][1<<10][31]; void dfs(int cond,int sum,int pos){ if(pos>n){ c[++top]=cond; s[top]=sum; return; } dfs(cond+(1<<pos-1),sum+1,pos+2); dfs(cond,sum,pos+1); } int main(){ scanf("%d%d",&n,&k); dfs(0,0,1);//处理出一行的所有状态 for(int i=1;i<=top;i++)f[1][c[i]][s[i]]=1; for(int i=2;i<=n;i++) for(int j=1;j<=top;j++)//一共有top种状态 for(int h=1;h<=top;h++){ if(c[j]&c[h])continue; if((c[j]<<1)&c[h])continue; if((c[j]>>1)&c[h])continue; for(int sum=k;sum>=s[j];sum--) f[i][c[j]][sum]+=f[i-1][c[h]][sum-s[j]]; } long long ans=0; for(int i=1;i<=top;i++)ans+=f[n][c[i]][k]; cout<<ans; return 0; }