zoukankan      html  css  js  c++  java
  • BZOJ1087: [SCOI2005]互不侵犯King

    BZOJ1087: [SCOI2005]互不侵犯King

    Description

    在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案。

    国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子。

    Input

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

    Output

    方案数。

    Sample Input

    3 2

    Sample Output

    16
    题解Here!

    状压DP的题一般数据范围都很小,比如这题。

    设 f [ i ][ j ][ s ] 就表示在只考虑前i行时,在前 i 行(包括第 i 行)有且仅有 s 个国王,且第 i 行国王的情况是编号为 j 的状态时情况的总数。

    gs[ x ] 表示此状态下这一行放的国王个数。

    于是状态转移方程长这样:f [ i ][ j ][ s ]=∑f [ i-1 ][ k ][ s-gs[ j ] ]

    而 k 就代表第 i-1 行的国王情况的状态编号。

    那怎么判断某国王周围八个方向是否有国王呢?

    在同一行国王之间的关系我们可以直接在预处理状态时舍去那些不符合题意的状态,那其他的情况呢?

    位运算!

    sit[j] & sit[k] (及上下有重复的king)

    (sit[j]<<1)  & sit[k] (及左上右下有重复king)

    sit[j]  & (sit[k]<<1) (及右上左下有重复king)

    于是就可以处理掉那些不符合题意的状态了。

    附代码:

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    using namespace std;
    int n,m,S=0,a[(1<<10)+1],b[(1<<10)+1];
    long long ans=0,dp[10][(1<<10)+1][100];
    inline int read(){
        int date=0,w=1;char c=0;
        while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}
        while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}
        return date*w;
    }
    void dfs(int x,int s,int sum){
        if(x>=n){
            a[++S]=s;
            b[S]=sum;
            return;
        }
        dfs(x+1,s,sum);
        dfs(x+2,s+(1<<x),sum+1);
    }
    int main(){
        n=read();m=read();
        dfs(0,0,0);
        for(int s=1;s<=S;s++)dp[1][s][b[s]]=1;
        for(int i=2;i<=n;i++)
        for(int j=1;j<=S;j++)
        for(int k=1;k<=S;k++){
            if((a[j]&a[k])||((a[j]<<1)&a[k])||(a[j]&(a[k]<<1)))continue;
            for(int s=m;s>=b[j];s--)dp[i][j][s]+=dp[i-1][k][s-b[j]];
        }
        for(int s=1;s<=S;s++)ans+=dp[n][s][m];
        printf("%lld
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    Java实现简单的图片浏览器
    ArrayList源码笔记
    JZ12 数值的整数次方算法笔记
    TCP的三次握手与四次挥手学习笔记
    Deepin安装LAMP环境
    Deepin安装Mysql(解决"没有可安装候选"问题)
    流行的Linux系统合集
    Win10超简单安装,菜鸡钊的装机经验分享
    Java入门(七)之面向对象-划重点
    Java入门(六)之常用的类
  • 原文地址:https://www.cnblogs.com/Yangrui-Blog/p/9368757.html
Copyright © 2011-2022 走看看