zoukankan      html  css  js  c++  java
  • 互不侵犯(洛谷P1896)

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

    输入输出:输入N,K,输出有几种放置方法。(N<=9,k<=n^2)

    样例输入输出:

    入:3 2

    出:16

    这道题看范围就显然是状压dp了吧。。。

    其实这道题和状压基础题玉米地(corn fields)非常相像,主要思路包括以下几点。

    1.同一行不能有相邻的国王。

    2.斜对角和正上正下不能有相邻的国王。

    3.一共只有k个国王。

    根据状压dp的一般尿性,肯定是要枚举状态的,那状态里面“ 1 ”,“ 0 ”表示什么含义呢?

    肯定是“ 1 ”表示这一行这个位置放国王,“ 0 ”表示不放啊(废话++)

    那思路就挺显然了。

    1.枚举状态S,判断(S&(S<<1))==0,只有这样的S才是合法状态

    2.枚举上一行状态s,判断((S&(s<<1))==0&&(S&(s>>1))==0&&(S&s)==0)分别对应右上,左上,正上。

    3.主要麻烦的是这个k,怎么处理已经放了多少国王呢,这里我们可以用类似背包的思想,新开一维表示已经放入的国王数,然后由上一行较少国王数的状态转移过来(是不是很像背包的二维代码那个转移?可以把国王总数看作背包的容量,每一个国王就是背包中的一个个物品)

    然后就没了。。。

    附上全部代码:

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int maxn=1e2+10;
    typedef long long LL;
    LL f[15][1<<10][80];
    int lowbit(int x){return x&-x;}
    int find(int x){
        int cnt=0;
        for(int i=x;i;i-=lowbit(i)){
            cnt++;
        }
        return cnt;
    }
    int main(){
        int n,k;
        scanf("%d%d",&n,&k);
        int Max=(1<<n)-1;
        f[0][0][0]=1;
        for(int i=1;i<=n;i++){
            for(int S=0;S<=Max;S++){
                int cnt=find(S);
                if((S&(S>>1))==0){
                    for(int s=0;s<=Max;s++){
                        if((S&s)==0 && ((S&(s<<1))==0) && (S&(s>>1))==0)
                        for(int kk=cnt;kk<=k;kk++){
                  //这里用kk保存这一行所放置的国王数,要注意,在S状态下,已经有cnt个国王放置了,所以要从这再往上遍历 f[i][S][kk]
    +=f[i-1][s][kk-cnt]; } } } } } LL ans=0; for(int S=0;S<=Max;S++){ ans+=f[n][S][k]; } printf("%lld",ans); return 0; }
  • 相关阅读:
    Java知识系统回顾整理01基础04操作符02关系操作符
    Java知识系统回顾整理01基础04操作符01算术操作符
    Java知识系统回顾整理01基础03变量09块
    Java知识系统回顾整理01基础03变量08表达式
    Java知识系统回顾整理01基础03变量07final关键字
    Java知识系统回顾整理01基础03变量06变量的作用域
    Java知识系统回顾整理01基础03变量05变量命名规则
    Java知识系统回顾整理01基础03变量04类型转换
    leetcode-----64. 最小路径和
    leetcode-----63. 不同路径 II
  • 原文地址:https://www.cnblogs.com/liu-yi-tong/p/13196053.html
Copyright © 2011-2022 走看看