码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2019-10-05 22:41:42      阅读:113      评论:0      收藏:0      [点我收藏+]

标签:ret   tin   std   多少   pre   棋盘   oid   stream   state   

题目描述

在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]互不侵犯(提高+/省选-)

标签:ret   tin   std   多少   pre   棋盘   oid   stream   state   

原文地址:https://www.cnblogs.com/little-cute-hjr/p/11625645.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!