#(状压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)
输出格式
所得的方案数
输入输出样例
3 2
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]互不侵犯(提高+/省选-)的主要内容,如果未能解决你的问题,请参考以下文章