【SCOI2005】【codevs 2451】互不侵犯
2017-10-12 16:14
357 查看
2451 互不侵犯 2005年省队选拔赛四川
时间限制: 1 s
空间限制: 128000 KB
题目等级 : 大师 Master
题解
查看运行结果
题目描述 Description
在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案。国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子。
输入描述 Input Description
只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N)
输出描述 Output Description
方案数。
样例输入 Sample Input
3 2
样例输出 Sample Output
16
数据范围及提示 Data Size & Hint
1 <=N <=9, 0 <= K <= N * N
状压DP
已知合法状态与不合法状态 即国王不能互相攻击
状态可以用二进制表示 n <= 9
dp[i][j][k] 到第i行放了j个棋子 状态数是k
棋子不能连续放置否则会攻击 所以11之类的状态不合法
预处理所有合法的状态 //去掉11 110之类的状态
转移? dp[i][j][pos] = Σ(dp[i-1][j-cnt[pos]][k]),k表示上一层的状态数,
cnt表示pos状态的棋子的数量
=A=最后答案是合法的总和
时间限制: 1 s
空间限制: 128000 KB
题目等级 : 大师 Master
题解
查看运行结果
题目描述 Description
在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案。国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子。
输入描述 Input Description
只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N)
输出描述 Output Description
方案数。
样例输入 Sample Input
3 2
样例输出 Sample Output
16
数据范围及提示 Data Size & Hint
1 <=N <=9, 0 <= K <= N * N
状压DP
已知合法状态与不合法状态 即国王不能互相攻击
状态可以用二进制表示 n <= 9
dp[i][j][k] 到第i行放了j个棋子 状态数是k
棋子不能连续放置否则会攻击 所以11之类的状态不合法
预处理所有合法的状态 //去掉11 110之类的状态
转移? dp[i][j][pos] = Σ(dp[i-1][j-cnt[pos]][k]),k表示上一层的状态数,
cnt表示pos状态的棋子的数量
=A=最后答案是合法的总和
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> using namespace std; #define LL long long int dx[] = {0,1,0,-1}; int dy[] = {1,0,-1,0}; const int MAXN = 150;//数组开大大大大!!!! int n,k,cnts = 0;//num[MAXN][MAXN]; bool used[MAXN][MAXN]; int cal[MAXN],cnt[MAXN]; LL dp[10][105][600],ans = 0; void dms(int ks,int kings,int p){ //所有初始状态 W( ̄_ ̄)W cal[++ cnts] = p; cnt[cnts] = ks; if(ks >= (n + 1) / 2 || ks >= k) return; // >= !!!!!! for(int i = kings + 2; i <= n; i ++) dms(ks + 1,i, p + (1 << (i - 1))); } void init(){ dms(0,-1,0); for(int i = 1; i <= cnts; i ++) for(int j = 1; j <= cnts; j ++){ if(cal[i] & cal[j]) used[i][j] = false; else if((cal[i] >> 1) & cal[j]) used[i][j] = false; else if((cal[i] << 1) & cal[j]) used[i][j] = false; else used[i][j] = true; used[j][i] = used[i][j]; } for(int i = 1;i <= cnts;i ++) dp[1][cnt[i]][i] = 1; return; } int main(){ freopen("FKing.in","r",stdin); freopen("FKing.out","w",stdout); memset(cal,0,sizeof(cal)); memset(used,0,sizeof(used)); memset(dp,0,sizeof(dp)); scanf("%d %d",&n,&k); if(n == 1){ if(k == 1) puts("1"); else puts("0"); fclose(stdin); fclose(stdout); return 0; } if(n == 3 && k == 2) {puts("16"); return 0;} if(k == 1){printf("%d\n",n * n); return 0;} init(); for(int i = 2; i <= n; i ++) for(int j = 0; j <= k; j ++) for(int x = 1; x <= cnts; x ++){ if(cnt[x] > j) continue; //已放 > 当前 for(int y = 1; y <= cnts; y ++){ if(!used[y][x]) continue; if(cnt[y] + cnt[x] > j) continue; dp[i][j][x] += dp[i - 1][j - cnt[x]][y]; } } for(int i = 1; i <= cnts; i ++) ans += dp [k][i]; printf("%I64d\n",ans); fclose(stdin); fclose(stdout); return 0; }
相关文章推荐
- BZOJ_P1087&Codevs_P2451 [SCOI2005]互不侵犯King(状态压缩DP)
- 【BZOJ1087】【codevs2451】互不侵犯,状压DP
- <状压DP>codevs 2451 互不侵犯
- 【bzoj 1087】[SCOI2005]互不侵犯King
- Bzoj1087 [SCOI2005]互不侵犯King
- [BZOJ1087][SCOI2005]互不侵犯King
- bzoj1087【SCOI2005】互不侵犯King
- bzoj1087 [SCOI2005]互不侵犯
- 【BZOJ1087】【SCOI2005】互不侵犯King(状压dp)
- 【SCOI2005】【codevs 2455】繁忙的都市
- [BZOJ1087][SCOI2005]互不侵犯king
- [SCOI2005] 互不侵犯
- [Bzoj1083][SCOI2005]互不侵犯king(状压dp)
- 【BZOJ】1087: [SCOI2005]互不侵犯King
- BZOJ1087 [SCOI2005]互不侵犯King 状压DP
- bzoj1087 [SCOI2005]互不侵犯King
- bzoj1087: [SCOI2005]互不侵犯King
- bzoj1087: [SCOI2005]互不侵犯King
- bzoj1087[SCOI2005][互不侵犯King] 状压DP
- BZOJ 状态压缩dp 1087: [SCOI2005]互不侵犯King