zoukankan      html  css  js  c++  java
  • BZOJ1087 [SCOI2005]互不侵犯King 状态压缩动态规划

    欢迎访问~原文出处——博客园-zhouzhendong

    去博客园看该题解


    题目传送门 - BZOJ1087


    题意概括

      在n*n的棋盘上面放k个国王,使得他们互相无法攻击,问有多少种摆法。


    题解

      dp[i][j][x]表示前i行,状态为j,总共放了x个国王的方案总数。

      然后简单的转移一下即可。

      当然这样要炸。

      只需要在这之前把每行的合法情况筛选一下即可,这样的情况总数不到100。

      然后就可以了。


    代码

    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <cstdlib>
    #include <cmath>
    using namespace std;
    typedef long long LL;
    const int S=(1<<9)+5;
    int n,k;
    int sit[S],bitsum[S],sz;
    LL dp[11][S][100];
    int cnt1(int x){
        int ans=0;
        while (x){
            ans+=x&1;
            x>>=1;
        }
        return ans;
    }
    int main(){
        scanf("%d%d",&n,&k);
        sz=0;
        for (int i=0;i<(1<<n);i++)
            if (!(i&(i<<1)))
                sit[++sz]=i,bitsum[sz]=cnt1(i);
        memset(dp,0,sizeof dp);
        dp[0][1][0]=1;
        for (int i=0;i<n;i++)
            for (int j=1;j<=sz;j++)
                for (int x=0;x<=k;x++){
                    if (!dp[i][j][x])
                        continue;
                    for (int y=1;y<=sz;y++)
                        if (!(sit[j]&sit[y])&&!(sit[j]&(sit[y]<<1))&&!((sit[j]<<1)&sit[y])&&x+bitsum[y]<=k)
                            dp[i+1][y][x+bitsum[y]]+=dp[i][j][x];
                }
        LL ans=0;
        for (int i=1;i<=sz;i++)
            ans+=dp[n][i][k];
        printf("%lld",ans);
        return 0;
    }
  • 相关阅读:
    codechef FNCS
    bzoj2653 middle
    CF698F Coprime Permutation
    CF538H Summer Dichotomy
    CF930E Coins Exhibition
    CF468D Tree
    CF528E Triangles3000
    BZOJ 4066: 简单题
    BZOJ 4300: 绝世好题
    BZOJ 4520: [Cqoi2016]K远点对
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/BZOJ1087.html
Copyright © 2011-2022 走看看