zoukankan      html  css  js  c++  java
  • 互不侵犯King(bzoj 1087)

    Description

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

    Input

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

    Output

      方案数。

    Sample Input

    3 2

    Sample Output

    16
    /*
      一看就是状压DP,而且状态也很好设,dp[i][j][s]表示前i行填了j个国王,第i行的状态是s的方案数。
      但是这样直接转移,状态太多,会超时,我们发现,由于不能攻击到相邻的,所以每一行的状态是不多的,可以预处理一下。 
    */
    #include<cstdio>
    #include<iostream>
    #define M 600
    #define lon long long
    using namespace std;
    lon dp[10][100][M];
    int map[M][M],stay[M],num[M],m,n,k;
    void dfs(int s,int last,int t){
        stay[++m]=s;
        num[m]=t;
        if(t>=k) return;
        for(int i=last+2;i<=n;i++)
            dfs(s+(1<<i-1),i,t+1);
    }
    int main(){
        scanf("%d%d",&n,&k);
        dfs(0,-1,0);
        for(int i=1;i<=m;i++)
            for(int j=1;j<=m;j++)
                if(stay[i]&stay[j]||((stay[i]<<1)&stay[j])||((stay[i]>>1)&stay[j]))
                    map[i][j]=1;
        dp[0][0][1]=1;
        for(int i=1;i<=n;i++)
            for(int j=0;j<=k;j++)
                for(int s1=1;s1<=m;s1++){
                    if(num[s1]>j) continue;
                    for(int s2=1;s2<=m;s2++)
                        if(!map[s1][s2]&&num[s1]+num[s2]<=j)
                            dp[i][j][s1]+=dp[i-1][j-num[s1]][s2];
                }
        lon ans=0;
        for(int i=1;i<=m;i++) ans+=dp[n][k][i];
        printf("%lld",ans);
        return 0;
    }
  • 相关阅读:
    GUI编程基础
    MyBatisPlus详解
    MYSQL数据库优化(一)
    设计模式遵循的原则
    MYSQL计算连续与不连续区间的方法
    CentOS安装MySQL5.7多实例步骤详解
    CentOS下安装Mysql 8.0步骤详解
    RDD和DataFrame和DataSet三者间的区别
    Spark读取Mysql,Redis,Hbase数据(一)
    Spark中Broadcast的理解
  • 原文地址:https://www.cnblogs.com/harden/p/6492912.html
Copyright © 2011-2022 走看看