BZOJ 1087 (状态压缩DP)
2015-12-06 08:59
453 查看
1087: [SCOI2005]互不侵犯King
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 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 2Sample 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;
}
相关文章推荐
- php 入门基础 三
- 【linux】基本I/O操作&标准I/O操作(c语言编程)
- 小鑫的城堡
- Android监听耳机按键事件
- UVa 11137 - Ingenuous Cubrency
- 电影节
- Hadoop中数据序列化的常用方式:SequenceFile, Avro, Thrift, ProtoBuff -- 待完善
- 二分练习
- 最短路径
- 内核阅读之浅析Linux2.6.34内核路由数据转发(二)
- 程序猿必须克服的十大编程禁忌
- php入门基础 二
- 走迷宫
- 【Leetcode】Find Peak Element
- Windows 10 Mobile 演示:插入耳机自动执行 APP
- Ubiquitous Religions
- Hadoop的HA机制
- 【XML解析(三)】PULL解析XML
- 程序猿必须克服的十大编程禁忌
- 救基友记3