• 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;
    }
  • 相关阅读:
    MAVLINK协议
    rtt之通用bootloader
    easy flash &easy log
    电源适配器DC插头规格
    Jquery实现仿腾讯微薄的广播发表
    可供前端工程师选择的精彩CSS框架
    javascript实现记录文本框内文字个数
    Jquery仿IGoogle实现可拖动窗口(源码)
    jquery javascript 回到顶部功能
    常用的经典jquery代码[转]
  • 原文地址:https://www.cnblogs.com/dream-maker-yk/p/9676343.html
Copyright © 2020-2023  润新知