码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj[1087][SCOI2005]互不侵犯King

时间:2016-12-09 00:06:59      阅读:257      评论:0      收藏:0      [点我收藏+]

标签:for   pre   class   int   long   print   log   lld   data   

Description

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

Input

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

Output

  方案数。

Sample Input

3 2

Sample Output

16

题解

#include<stdio.h>
int n,m;
bool st[600],ts[600][600];
long long sum[600],f[2][121][600];
int main(){
    scanf("%d%d",&n,&m);
    for(int i=0;i<(1<<n);i++)
        if(!((i>>1)&i)){
            for(int x=i;x;x>>=1)
                sum[i]+=x&1;
            st[i]=1;
        }
    for(int i=0;i<(1<<n);i++){
        if(!st[i])
            continue;
        for(int j=0;j<=i;j++)
            if(st[j]&&(!(i&j))&&(!(i&(j>>1)))&&(!((i>>1)&j)))
                ts[i][j]=ts[j][i]=1;
    }
    int c=0;
    for(int i=0;i<(1<<n);i++)
        f[c][sum[i]][i]=1;
    for(int t=1;t<n;t++){
        c^=1;
        for(int i=0;i<(1<<n);i++)
            for(int j=0;j<=m;j++)
                f[c][j][i]=0;
        for(int i=0;i<(1<<n);i++){
            if(!st[i])
                continue;
            for(int j=0;j<(1<<n);j++)
                if(st[j]&&ts[i][j])
                    for(int p=sum[j];p<=m-sum[i];p++)
                        f[c][p+sum[i]][i]+=f[c^1][p][j];
        }
    }
    long long ans=0;
    for(int i=0;i<(1<<n);i++)
        ans+=f[c][m][i];
    printf("%lld\n",ans);
    return 0;
}

 

bzoj[1087][SCOI2005]互不侵犯King

标签:for   pre   class   int   long   print   log   lld   data   

原文地址:http://www.cnblogs.com/keshuqi/p/6146811.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!