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

    http://www.lydsy.com/JudgeOnline/problem.php?id=1087

    Description

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

    Input

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

    Output

      方案数。

    Sample Input

    3 2

    Sample Output

    16

    ——————————————————————————————

    n很小,暴力太麻烦,考虑状压。

    设f[i][j][k]表示前i行放j个国王且第i行排成k情况的时候的情况数有多少。

    g[i]表示一行国王排成i情况的时候有几个国王。

    转移的时候显然是f[i][j][k]+=f[i-1][j-g[k]][l]

    其中保证l合法,并且j最小值为g[k]+g[l]。

    于是得到算法构架:

    枚举i,枚举k,判断k的合法性,枚举l,判断l的合法性,枚举j,计算。

    Q1:g怎么算?

    A1:求g[i],我们可以通过将i右移,然后判断i最后一位为0还为1,所以答案为:g[i]=g[i>>1]+(i&1);

    Q2:如何判断状态合法?

    A2:我们判断相邻行i和j状态之间是否合法,首先判断i和j本身是否合法——通过将本身左移,再和原状态&一下,如果不为0就一定撞上了。

    再考虑i和j,同样的思路,将j左/右移和i&(当然反过来也可以),如果不为0就一定撞上了。

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
    typedef long long ll;
    const int N=512;
    const int INF=2147483647;
    inline int read(){
        int X=0,w=0;char ch=0;
        while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
        while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
        return w?-X:X;
    }
    int g[N];
    ll ans,f[10][100][N];
    int main(){
        int n,m;
        scanf("%d%d",&n,&m);
        if(m>25||m>=n*n)puts("0");
        else{
        int t=1<<n;f[0][0][0]=1;
        for(int i=1;i<t;i++)g[i]=g[i>>1]+(i&1);
        for(int i=1;i<=n;i++){
            for(int j=0;j<t;j++){
            if(g[j]<=m&&!(j&j>>1)){
                for(int k=0;k<t;k++){
                if(g[k]<=m&&!(k&k>>1)&&!(k&j)&&!(j&k>>1)&&!(j&k<<1)){
                    for(int l=g[j]+g[k];l<=m;l++){
                    f[i][l][j]+=f[i-1][l-g[j]][k];
                    }
                }
                }
            }
            }
        }
        for(int i=0;i<t;i++)ans+=f[n][m][i];
        printf("%lld
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    百度地图常用 获取中心点 缩放级别等
    sqlserver 临时表,多用户同时访问冲突吗?
    批量改ID 行形式
    C# post Json数据
    windows 激活venv问题
    spring 改变url
    conductor编译镜像
    springboot教程
    Microsoft Visual C++ Compiler for Python 2.7
    java 方法引用(method reference)
  • 原文地址:https://www.cnblogs.com/luyouqi233/p/8244537.html
Copyright © 2011-2022 走看看