#(状压DP)P1896 [SCOI2005]互不侵犯(提高+/省选-)

Posted little-cute-hjr

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了#(状压DP)P1896 [SCOI2005]互不侵犯(提高+/省选-)相关的知识,希望对你有一定的参考价值。

题目描述

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

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

输入格式

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

输出格式

所得的方案数

输入输出样例

输入 #1
3 2
输出 #1
16


#include<cstdio>
#include<iostream>
using namespace std;
int n,k;
long long num[12000],s0,st[12000],f[10][155][100],ans;
void Prepare()

int m;
for(int i=0;i<(1<<n);i++)

m=0;
if(i&(i<<1))
continue;
// calc state
for(int j=0;j<n;j++)
if((1<<j)&i) m++;
st[++s0]=i;
num[s0]=m;//calc state kings


void dp()

int kk;
f[0][1][0]=1;
for(int i=1;i<=n;i++)
for(int j=1;j<=s0;j++)
for(int kk=0;kk<=k;kk++)

if(kk>=num[j])
for(int t=1;t<=s0;t++)

if(!(st[j]&st[t]) && !((st[j]<<1)&st[t]) && !((st[j]>>1)&st[t]))
f[i][j][kk]+=f[i-1][t][kk-num[j]];


for(int i=1;i<=s0;i++)
ans+=f[n][i][k];
printf("%lld",ans);


int main()

scanf("%d %d",&n,&k);
Prepare();
dp();
return 0;

以上是关于#(状压DP)P1896 [SCOI2005]互不侵犯(提高+/省选-)的主要内容,如果未能解决你的问题,请参考以下文章

P1896 [SCOI2005]互不侵犯

洛谷P1896SCOI2005互不侵犯King

Luogu P1896 [SCOI2005]互不侵犯

P1896 [SCOI2005]互不侵犯

[SCOI2005]互不侵犯

P1896 [SCOI2005]互不侵犯