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; }
  • 相关阅读:
    真正的e时代
    在线手册
    UVA 10616 Divisible Group Sums
    UVA 10721 Bar Codes
    UVA 10205 Stack 'em Up
    UVA 10247 Complete Tree Labeling
    UVA 10081 Tight Words
    UVA 11125 Arrange Some Marbles
    UVA 10128 Queue
    UVA 10912 Simple Minded Hashing
  • 原文地址:https://www.cnblogs.com/liu-yi-tong/p/13196053.html
Copyright © 2011-2022 走看看