[SCOI2005]互不侵犯

[SCOI2005]互不侵犯

题目描述

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

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

输入输出格式

输入格式:

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

输出格式:

所得的方案数

输入输出样例

输入样例#1:

3 2

输出样例#1:

16

\(n \le 9\)可以看粗应该是个状压DP

所以就可以高高兴兴个设状态了

\(f[i][j][k]\)表示前\(i\) 行 最后一行状态为\(j\)\(k\)个的方案数

需要两个函数判断状态合不合法还有放置的个数

inline int bitcnt(int x,int ans=0){
    for(;x;x&=(x-1),++ans);
    return ans;
}

用来判断二进制中有几个一(\(x\&=x-1\)是不是很熟悉没错就是今年初赛题)

inline bool pd(int x){
    return (((x<<1)&x)||((x>>1)&x));
}

这个用来判断一个数合不合法(一个1左右不能有另一个1)

然后就可以列状态转移方程了

\(\displaystyle f[i][j][k]=\sum_{l与j合法}f[i-1][l][k-bitcnt(k)]\)

#include<iostream>
#include<cstdio>
using namespace std;
#define int long long 
int mian(){
    int s=0,f=1;char ch;
    while(!isdigit(ch=getchar()))(ch=='-')&&(f=-1);
    for(s=ch-'0';isdigit(ch=getchar());s=s*10+ch-'0');
    return s*f;
}
/*
子供の时の梦は言えますか
    その梦すら 沟に 舍てたのは
*/
int f[10][(1<<10)+1][100];
int n,m;
inline int bitcnt(int x,int ans=0){
    for(;x;x&=(x-1),++ans);
    return ans;
}
inline bool pd(int x){
    return (((x<<1)&x)||((x>>1)&x));
}
signed main(){
    n=mian(),m=mian();
    const int U = (1<<n)-1;
    f[0][0][0]=1;
    for(int i=1;i<=n;++i){
        for(int k=0;k<=U;++k){
            if(pd(k))continue;
            for(int l=0;l<=U;++l){
                if(pd(l))continue;
                if(l&k)continue;
                if((l>>1)&k)continue;
                if((l<<1)&k)continue;
                // cout<<k<<' '<<l<<endl;
                int c=bitcnt(k);
                for(int o=c;o<=m;++o)
                    f[i][k][o]+=f[i-1][l][o-c];
            }
        }
    }
    int ans=0;
    for(int i=0;i<=U;++i)ans+=f[n][i][m];
    cout<<ans<<endl;
    return 0;
}

转载于:https://www.cnblogs.com/eric-walker/p/9794121.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值