• 【洛谷 1896】互不侵犯_new


    题目描述

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

    注:数据有加强(2018/4/25)

    输入格式

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

    输出格式

    所得的方案数

    输入输出样例

    输入 #1
    3 2
    
    输出 #1
    16

    题解:更新版本的嘻嘻。

    #include<iostream>
    #include<algorithm>
    #include<queue>
    #include<cmath>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    using namespace std;
    typedef long long ll;
    int n,k;
    ll dp[13][15002][81],sum,ans,cnt; 
    ll st[787878],ki[78787];
    void init(){
        scanf("%d %d",&n,&k);
        int op=(1<<n);
        for(int i=0;i<op;i++){
            if(!((i<<1)&i)){
                st[++cnt]=i;
                int mt=i;
                while(mt){
                    ki[cnt]+=mt%2;
                    mt>>=1;
                }
            }
        } 
    }
    void work(){
        for(int i=1;i<=cnt;i++)
            if(ki[i]<=k) dp[1][i][ki[i]]=1;
        for(int i=2;i<=n;i++){//枚举行数 
            for(int j=1;j<=cnt;j++){//枚举状态 
                for(int p=1;p<=cnt;p++){//枚举上一行状态
                    if((st[j] & st[p])||((st[j]<<1) & st[p])||(st[j] & (st[p]<<1))) continue;
                    for(int s=1;s<=k;s++){
                        if(ki[j]+s>k) continue; 
                        dp[i][j][ki[j]+s]+=dp[i-1][p][s];
                    }    
                } 
            }
        }
        for(int i=1;i<=n;i++)
            for(int j=1;j<=cnt;j++)
                ans+=dp[i][j][k];
        cout<<ans; 
    }
    int main(){
        //freopen("1896.in","r",stdin);
        //freopen("1896.out","w",stdout);
        init(); work();
        return 0;
    }
  • 相关阅读:
    idea初始化配置
    常用网址
    linux改错了profile文件
    获得ip地址[转载]
    java 基本数据类型转换
    log4j配置概要
    HTTP状态码
    HTTP 的请求方式
    10、类和方法
    9、一切都是对象
  • 原文地址:https://www.cnblogs.com/wuhu-JJJ/p/11328157.html
Copyright © 2020-2023  润新知