BZOJ 1087 【SCOI2005】 互不侵犯King

Description

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

Input

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

Output

  方案数。

 
  智障状压dp题。 $f_{i,j,S}$表示前$i$行放了$j$个国王,最后一行状态为$S$的方案数。没开long longWA了两发简直智障。
  下面贴代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)

using namespace std;
typedef long long llg;

int n,k;
llg f[10][82][1<<10],ans;

int main(){
    File("a");
    scanf("%d %d",&n,&k);
    f[0][0][0]=1;
    for(int i=1;i<=n;i++)
        for(int j=0;j<=k;j++)
            for(int S=0;S<(1<<n);S++)
                if((!((S<<1)&S)) && (!((S>>1)&S))){
                    int x=S,nn=0;
                    while(x) nn+=(x&1),x>>=1;
                    if(nn<=j)
                        for(int s=0;s<(1<<n);s++)
                            if((!(s&S)) && (!((s<<1)&S)) && (!((s>>1)&S)))
                                f[i][j][S]+=f[i-1][j-nn][s];
                }
    for(int S=0;S<(1<<n);S++)
        ans+=f[n][k][S];
    printf("%lld",ans);
}
posted @ 2016-09-27 17:26  lcf2000  阅读(211)  评论(0编辑  收藏  举报