• BZOJ1087 SCOI2005 互不侵犯King 【状压DP】


    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


    我们先预处理出哪些状态是合法的,即一个二进制状态没有连续的1,然后再预处理出哪些状态是可以相互转化的,即对于x状态i位有国王,y状态的第i-1,i,i+1位都不能有国王,然后再DP一下就好了,最后统计答案


    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    #define LL long long
    #define N 1000
    LL dp[10][100][N],cnt[N];
    bool vis[N],g[N][N];
    int main(){
        LL n,m;scanf("%lld%lld",&n,&m);
        LL up=(1<<n)-1;
        for(LL i=0;i<=up;i++)
            if(((i>>1)&i)==0){
                for(LL j=i;j;j>>=1)cnt[i]+=(j&1);
                vis[i]=1;
            }
        for(LL i=0;i<=up;i++)if(vis[i])
            for(LL j=0;j<=up;j++)if(vis[j])
                if((i&j)==0&&((i>>1)&j)==0&&((i<<1)&j)==0)
                    g[i][j]=1;
        for(LL i=0;i<=up;i++)if(vis[i])dp[1][cnt[i]][i]=1;
        for(LL i=2;i<=n;i++)
            for(LL j=0;j<=up;j++)if(vis[j])
                for(LL k=0;k<=up;k++)if(vis[k]&&g[j][k])
                    for(LL l=cnt[j];l+cnt[k]<=m;l++)
                        dp[i][l+cnt[k]][k]+=dp[i-1][l][j];
        LL ans=0;
        for(LL i=0;i<=up;i++)ans+=dp[n][m][i];
        printf("%lld",ans);
        return 0;
    }
  • 相关阅读:
    Js 作用域链
    JS 上下文模式
    javascript
    HTTP概念进阶
    JavaScript运行机制详解
    浅谈循环中setTimeout执行顺序问题
    Js 运行机制 (重点!!)
    javascript
    jQuery 知识点总结
    Educational Codeforces Round 87 (Rated for Div. 2)
  • 原文地址:https://www.cnblogs.com/dream-maker-yk/p/9676343.html
Copyright © 2020-2023  润新知