在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案。国王能攻击到它上下左右,以及左上
左下右上右下八个方向上附近的各一个格子,共8个格子。
标签:nbsp scan += 状压dp log discus stat time 枚举
Time Limit: 10 Sec Memory Limit: 162 MB
在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案。国王能攻击到它上下左右,以及左上
左下右上右下八个方向上附近的各一个格子,共8个格子。
只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N)
方案数。
3 2
16
# include <iostream> # include <cstdio> # include <cstring> using namespace std; const int N = 1 << 9; int cnt,state[102],num[102],P,n,c; long long f[10][102][102]; int lowbit(int r){ return r & -r; } void work(){ for(int i = 0;i < P;i++){ int pre = lowbit(i),r = i - pre;bool flag = true; while(r){ if(lowbit(r) / pre <= 2){ flag = false;break; } pre = lowbit(r);r -= pre; } if(flag)state[++cnt] = i; } for(int i = 1;i <= cnt;i++){ int r = state[i]; while(r){ r -= lowbit(r); num[i]++; } } } int main(){ scanf("%d %d",&n,&c);P = 1 << n; work(); f[0][1][0] = 1LL; for(int i = 1;i <= n;i++){ for(int j = 1;j <= cnt;j++){ for(int k = 1;k <= cnt;k++){ for(int l = 0;l <= c;l++){ if(state[j] & state[k])continue; if((state[j] >> 1) & state[k])continue; if((state[j] << 1) & state[k])continue; f[i][j][l + num[j]] += f[i - 1][k][l]; } } } } long long ans = 0; for(int i = 1;i <= cnt;i++){ ans += f[n][i][c]; } printf("%lld\n",ans); }
[Bzoj1083][SCOI2005]互不侵犯king(状压dp)
标签:nbsp scan += 状压dp log discus stat time 枚举
原文地址:http://www.cnblogs.com/lzdhydzzh/p/7787505.html