您的位置:首页 > 其它

BZOJ 1087 (状态压缩DP)

2015-12-06 08:59 453 查看

1087: [SCOI2005]互不侵犯King

Time Limit: 10 Sec Memory Limit: 162 MB

Submit: 2274 Solved: 1333

[Submit][Status][Discuss]

Description

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

Input

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

Output

方案数。

Sample Input

3 2

Sample Output

16

解题思路:

状态压缩DP

#include<iostream>

#include<cstdio>

#include<cstring>

#include<algorithm>

using namespace std;

int n,k;

long long f[11][90][600];

int wei[11];

int zan[11];

int i,j,g,h,y;

int main()

{

scanf("%d %d",&n,&k);

memset(f,0,sizeof(f));

f[0][0][0]=1;

int sss=(1<<n)-1;

for (i=1;i<=n;++i)

for (j=0;j<=k;++j)

for (g=0;g<=sss;++g)

{

int u=g; int sug=0; memset(wei,0,sizeof(wei));

bool mm=true;

int ji=1;

while (u>0)

{

if (u%2==1) {++sug;wei[ji]=1;if (wei[ji-1]==1) mm=false;}

++ji;

u=u/2;

}

if (mm==false) continue;

if (sug+j>k){continue;}

for (h=0;h<=sss;++h)

if (f[i-1][j][h]>0)

{

memset(zan,0,sizeof(zan));

u=h; ji=1;

while (u>0)

{

if (u%2==1) {zan[ji]=1;}

++ji;

u=u/2;

}

bool m=true;

for (y=1;y<=n;++y)

if (zan[y]==1)

{

if (y-1>=0 && wei[y-1]==1) m=false;else

if (y+1<=n && wei[y+1]==1) m=false;else

if (wei[y]==1) m=false;

if (m==false) break;

}

if (m==true)

{

f[i][j+sug][g]=f[i][j+sug][g]+f[i-1][j][h];

}

}

}

long long sum=0;

for (int i=0;i<=sss;++i)

if (f
[k][i]>0)

{

sum+=f
[k][i];

}

cout<<sum;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: