互不侵犯(luogu 1896)

题目描述

在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案。国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子。

注:数据有加强(2018/4/25)

输入输出格式

输入格式:

 

只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N)

 

输出格式:

 

所得的方案数

 

输入输出样例

输入样例
3 2
输出样例
16

 


第一篇状压,好开心~

虽然数据点很小,但数据量可非常大,注意开long long 

 

code

#include<stdio.h> 
#include<algorithm> 
using namespace std;
int n,m,cnt,cas[1000];
long long f[10][1000][1000],num[1000];

int getsum(int x) {
    int re=0;
    while(x) re+=(x&1),x>>=1;
    return num[cnt]=re;
}

int main()
{
    scanf("%d%d",&n,&m);
    int mx=(1<<n)-1;
    for(int i=0;i<=mx;++i) if(!((i<<1)&i)) {
        cas[++cnt]=i;
        f[1][cnt][getsum(i)]=1;
    }
    
    for(int i=2;i<=n;++i) {
        for(int j=1;j<=cnt;++j) {
            int x=cas[j];
            for(int k=1;k<=cnt;++k) {
                int y=cas[k];
                if(x&y || x&(y>>1) || x&(y<<1)) continue;
                for(int l=0;l<=m;++l) f[i][j][num[j]+l]+=f[i-1][k][l];
            }
        }
    }
    long long ans=0;
    for(int i=1;i<=cnt;++i) ans+=f[n][i][m];
    printf("%lld",ans);
    return 0;
}

 

posted @ 2018-10-09 17:11  qseer  阅读(183)  评论(0编辑  收藏  举报