[BZOJ] 1087 [SCOI2005]互不侵犯King
Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 5337 Solved: 3105
[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
HINT
Source
状压dp,一开始想写二维的无果。。
f[第i行][状态j][共有k个1]
#include<iostream>
#include<cstdio>
using namespace std;
long long f[20][513][105];
int n,lim,m;
int cnt[513];
void init(){
for(int i=0;i<=512;i++) cnt[i]=cnt[i>>1]+(i&1);
}
inline bool invaild(int x){return x&((x&(x<<1)));}
inline bool check(int x,int y){return ((x|(x<<1)|(x>>1))&y);}
signed main(){
cin>>n>>lim;
m=1<<n;
init();
for(int i=0;i<=m;i++) f[1][i][cnt[i]]=1;
for(int i=2;i<=n;i++){
for(int j=0;j<m;j++){
if(invaild(j)) continue;
for(int k=0;k<m;k++){
if(invaild(k)) continue;
if(check(j,k)) continue;
for(int l=cnt[k];l<=lim;l++){
f[i][k][l]+=f[i-1][j][l-cnt[k]];
}
}
}
}
int ans=0;
for(int i=0;i<m;i++) ans+=f[n][i][lim];
cout<<ans<<endl;
return 0;
}
本文来自博客园,作者:GhostCai,转载请注明原文链接:https://www.cnblogs.com/ghostcai/p/9247401.html