洛谷P1896 [SCOI2005]互不侵犯King

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;
}

 

posted @ 2017-10-24 21:02  Echo宝贝儿  阅读(162)  评论(0编辑  收藏  举报