BZOJ 1087 [SCOI2005]互不侵犯King(状压DP)

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

思路:状压dp,dp[i][j][k]为前i行放了j个,第i行状态为k

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<deque>
#include<set>
#include<vector>
#include<map>
#include<functional>
    
#define fst first
#define sc second
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lc root<<1
#define rc root<<1|1
#define lowbit(x) ((x)&(-x)) 

using namespace std;

typedef double db;
typedef long double ldb;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PI;
typedef pair<ll,ll> PLL;

const db eps = 1e-6;
const int mod = 998244353;
const int maxn = 2e6+100;
const int maxm = 2e6+100;
const int inf = 0x3f3f3f3f;
const db pi = acos(-1.0);

ll dp[20][200][2000];
int n, k;
int num[2000];
int ys[2000];

int main(){
    mem(dp, 0);
    mem(ys, 0);
    scanf("%d %d", &n, &k);
    for(int i = 0; i < (1<<n); i++){
        int p = i;
        int cnt = 0;
        while(p){
            if(p&1)cnt++;
            p>>=1;
        }
        num[i]=cnt;
    }
    for(int i = 0; i < (1<<n); i++){
        if(((i<<1)&i) ||((i>>1)&i)){
            continue;
        }
        ys[i] = 1;
        dp[1][num[i]][i]=1;
    }
    for(int i = 2; i <= n; i++){
        for(int j = 0; j <= k; j++){
            for(int p = 0; p < (1<<n); p++){//now
                if(!ys[p])continue;
                if(num[p]>j)continue;
                for(int x = 0; x < (1<<n); x++){//last status from i-1
                    if(!ys[x])continue;
                    if((p&x)||((p<<1)&x)||(p>>1)&x)continue;
                    dp[i][j][p] += dp[i-1][j-num[p]][x];

                }
            }
        }
    }
    ll ans = 0;
    for(int i = 0; i < (1<<n); i++){
        ans += dp[n][k][i];
    }
    printf("%lld", ans);
    return 0;

}

 

posted @ 2018-10-22 20:34  wrjlinkkkkkk  阅读(150)  评论(0编辑  收藏  举报