• 1087: [SCOI2005]互不侵犯King


    1087: [SCOI2005]互不侵犯King

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 4276  Solved: 2471
    [Submit][Status][Discuss]

    Description

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

    Input

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

    Output

      方案数。

    Sample Input

    3 2

    Sample Output

    16

    HINT

     

    Source

    /*
    * @Author: LyuC
    * @Date:   2017-09-03 21:24:43
    * @Last Modified by:   LyuC
    * @Last Modified time: 2017-09-04 21:55:56
    */
    
    /*
     题意:在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案。国王能攻击到它上下左右,以及左上
        左下右上右下八个方向上附近的各一个格子,共8个格子。
     
     思路:类似八皇后问题,k>n的情况方案数为0,然后剩下的搜索解决
    
     错误:这个和八皇后问题不一样,king只能攻击相邻一格,状压DP
    
     dp[i][j][k]表示第i行,j状态,已经按放k个棋子的状态
    
     状态转移:dp[i][j][cnt=从j状态中的棋子数枚举到需要放的总的棋子数]+=
        dp[i-1][上一行能满足下一行是j状态的状态][cnt-j状态的棋子数]
    
     总的来说动态规划就是抽象出来状态,就很简单了
    */
    #include <bits/stdc++.h>
    
    #define MAXN 15
    #define MAXT 1024
    #define MAXK 105
    #define LL long long
    
    using namespace std;
    
    LL n,k;
    LL dp[MAXN][MAXT][MAXK];//dp[i][j][k]表示第i行,第j种状态时,已经放下了k个棋子的方案数
    LL tol;
    LL cnt;
    LL res;
    
    bool ok(LL x,LL y){//判断上行的状态是否满足条件
        for(LL i=0;i<n;i++){
            if( (x&(1<<i)) ==0 ) continue;
    
            if(i==0){
                if( ( y&( 1<<i ) ) !=0 || ( y&( 1<<(i+1) ) ) !=0)
                    return false;
            }else if(i==n-1){
                if( ( y&( 1<<i ) ) !=0 || ( y&( 1<<(i-1) ) ) !=0)
                    return false;
            }else{
                if( ( y&( 1<<(i-1) ) ) !=0 || ( y&( 1<<(i+1) ) ) !=0 || ( y&( 1<<i ) ) !=0)
                    return false;
            }
        }
        return true;
    }
    
    LL judge(LL x){//判断这个状态是不是合格的
        LL cur=0;
        for(LL i=0;i<n;i++){
            if( ( x&(1<<i) ) !=0){
                if(i==0){
                    if( ( x&( 1<< (i+1) ) )!=0){
                        return -1;
                    }
                }else if(i==n-1){
                    if( ( x&(1<<(i+1)) )!=0 || ( x&(1<<(i-1)) )!=0 ){
                        return -1;
                    }
                }else{
                    if( ( x&(1<<(i-1)) )!=0){
                        return -1;
                    }
                }
                cur++;
            }
        }
        return cur;
    }
    
    inline void init(){
        memset(dp,0,sizeof dp);  
        res=0;  
    }
    
    int main(){
        // freopen("in.txt","r",stdin);
        init();
        scanf("%lld%lld",&n,&k);
    
        tol=(1<<n);
    
        for(LL i=0;i<tol;i++){//初始化状态
            cnt=judge(i);
            if(cnt!=-1){
                dp[0][i][cnt]=1;
            }
        }
    
        for(LL i=1;i<n;i++){//从第二行开始递推状态
            for(LL j=0;j<tol;j++){//枚举当前行的状态
                cnt=judge(j);
                if(cnt==-1) continue;
                for(LL l=0;l<tol;l++){//枚举上一行的状态
                    if(ok(j,l)==false) continue;
                    for(LL d=cnt;d<=k;d++){
                        dp[i][j][d]+=dp[i-1][l][d-cnt];
                    }
                }
            }
        }
    
        for(LL i=0;i<tol;i++){
            res+=dp[n-1][i][k];
        }
        printf("%lld
    ",res);
        return 0;
    }
  • 相关阅读:
    2015多校1006.First One
    2015多校.MZL's endless loop(欧拉回路的机智应用 || 构造)
    LUXURY 8
    矩阵快速幂模板
    博弈入门
    cf558c(bfs)
    LUXURY 7
    dfs序 + RMQ = LCA
    双端队列
    UVa-401 Palindromes
  • 原文地址:https://www.cnblogs.com/wuwangchuxin0924/p/7476072.html
Copyright © 2020-2023  润新知