zoukankan      html  css  js  c++  java
  • bzoj1087: [SCOI2005]互不侵犯King 状压dp

    Description

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

    Input

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

    Output

      方案数。

    题解

    玉米田(轻击有惊喜)的解法一样。预处理一行所有合法情况。由于是四周的八个格子都不能有国王,在判断时多一个左移、右移,然后dp扫一遍

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int mod=1e9;
    const int maxn=(1<<9)+10;
    typedef long long ll;
    int read(){
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    int n,k;
    int is[maxn];
    ll f[10][maxn][90];
    int main(){
        n=read();k=read();
        for(int i=0;i<(1<<n);i++){
            is[i]=((i&(i<<1))==0)&&((i&(i<<1))==0);
            if(is[i]){
                int num=__builtin_popcount(i);
                if(num>k)continue;
                f[1][i][num]=1;
            }
        }
        for(int i=2;i<=n;i++) for(int j=0;j<(1<<n);j++)
            if(is[j]){
                int num1=__builtin_popcount(j);
                for(int p=0;p<(1<<n);p++) if(((p&j)==0)&&((p&(j<<1))==0)&&((p&(j>>1))==0))
                    for(int q=0;q<=k-num1;q++) f[i][j][q+num1]+=f[i-1][p][q]; 
            }
        ll ans=0;
        for(int i=1;i<=n;i++) for(int j=1;j<(1<<n);j++)
            if(is[j])ans+=f[i][j][k];
        printf("%lld
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    for of 与 for in的区别
    Mac Item2 SSH免密登录Linux 服务器的两种方式
    组塞式,非阻塞式,同步异步
    Thrift_简介(基于C#)
    HTTP Error 500.22
    http协议
    IIS_部署出错
    JavaScript如何实现继承
    $(function(){})与 (function(){})() (function($){})() 的区别
    C#_反射机制
  • 原文地址:https://www.cnblogs.com/Nan-Cheng/p/9741583.html
Copyright © 2011-2022 走看看