HDU 4529 状态压缩DP
来源:互联网 发布:高清电视直播软件 编辑:程序博客网 时间:2024/06/08 12:23
状态压缩DP
题意:
Problem Description
郑厂长不是正厂长
也不是副厂长
他根本就不是厂长
还是那个腾讯公司的码农
一个业余时间喜欢下棋的码农
最近,郑厂长对八皇后问题很感兴趣,拿着国际象棋研究了好几天,终于研究透了。兴奋之余,坐在棋盘前的他又开始无聊了。无意间,他看见眼前的棋盘上只摆了八个皇后,感觉空荡荡的,恰好又发现身边还有几个骑士,于是,他想把这些骑士也摆到棋盘上去,当然棋盘上的一个位置只能放一个棋子。因为受八皇后问题的影响,他希望自己把这些骑士摆上去之后,也要满足每2个骑士之间不能相互攻击。
现在郑厂长想知道共有多少种摆法,你能帮助他吗?
骑士的下法:
每步棋先横走或直走一格,然后再往外斜走一格;或者先斜走一格,最后再往外横走或竖走一格(即走“日”字)。可以越子,没有”中国象棋”的”蹩马腿”限制。Input
输入第一行为一个整数T(1<=T<=8),表示有T组测试数据;
每组数据首先是一个整数N(1<=n<=10),表示要摆N个骑士上去;
接下来是一个8∗ 8的矩阵来描述一个棋盘,’.’表示这个位置是空的,′∗′ 表示这个位置上已经放了皇后了;
数据中的初始棋盘保证是一个合法的八皇后摆法。Output
对每组数据,请在一行内输出一个整数,表示合法的方案数。
Sample Input
21*...........*..........*.....*....*...........*..*.........*....2*...........*..........*.....*....*...........*..*.........*....
Sample Output
561409
思路:
就像前一个郑厂长系列一样,棋盘的状态需要压缩。不同的是这里不是求出最多放几个马,而是给出马的数量问有多少种在限制条件下放的可能数。显然之前的三维已经无法满足这个状态,需要增加一维马的数量去遍历每一行的所有状态。
定义:
当算到第r行状态为i的时候要加上r-1行所有的满足的状态j的个数,便是所有此状态情况,然后遍历第r行状态,最后求和既可。
#include <iostream>#include <cstdio>#include <cstring>using namespace std;const int maxn = 260;int num[maxn],pos;int map[10];int dp[8][12][maxn][maxn];void init(){ memset(dp,0,sizeof(dp)); memset(map,0,sizeof(map));}void state_num(){ pos = 0; for(int i = 0;i < (1<<8); i++) { int k = i; int number = 0; while(k) { if(k&1) number++; k >>= 1; } num[pos++] = number; }}int main(){// freopen("in.txt","r",stdin); int tt; scanf("%d",&tt); state_num(); while(tt--) { init(); int k; scanf("%d",&k); getchar(); for(int i = 0;i < 8; i++) { for(int j = 0;j < 8; j++){ char c; scanf("%c",&c); if(c == '*') { map[i] += (1<<j); } } getchar(); } for(int i = 0;i < pos; i++) { if(i&map[0]) continue; if(num[i] > k) continue; dp[0][num[i]][i][0] = 1; } for(int number = 0;number <= k; number++) { for(int i = 0;i < pos; i++) { if(i&map[1]) continue; if(num[i] > number) continue; for(int j = 0;j < pos; j++) { if(j&map[0]) continue; if((i<<2)&j || (i>>2)&j) continue; dp[1][number][i][j] += dp[0][number-num[i]][j][0]; } } } for(int r = 2;r < 8; r++) { for(int number = 0;number <= k; number++) { for(int i = 0;i < pos; i++) { if(i&map[r]) continue; if(num[i] > number) continue; for(int j = 0;j < pos; j++) { if(j&map[r-1]) continue; if((i<<2)&j || (i>>2)&j) continue; for(int t = 0;t < pos; t++) { if(t&map[r-2]) continue; if((i<<1)&t || (i>>1)&t) continue; if((j<<2)&t || (j>>2)&t) continue; dp[r][number][i][j] += dp[r-1][number-num[i]][j][t]; } } } } } int ans = 0; for(int i = 0;i < pos; i++) { for(int j = 0;j < pos; j++) { ans += dp[7][k][i][j]; } } printf("%d\n",ans); } return 0;}
- hdu 4529 状态压缩DP
- HDU 4529 状态压缩DP
- 【状态压缩dp】HDU
- hdu(3920)状态压缩+dp
- HDU 1074 状态压缩DP
- HDU 4049 状态压缩DP
- 【状态压缩DP】HDU 2167
- hdu 1565 状态压缩 dp
- HDU 1074 状态压缩dp
- HDU 1074 (状态压缩DP)
- HDU 3362 (状态压缩DP)
- hdu 4539 状态压缩DP
- hdu 1565 状态压缩dp
- hdu 3182 状态压缩DP
- Hdu 3811 状态压缩 DP
- hdu 1565 状态压缩DP
- hdu 2167 状态压缩DP
- hdu 4539 状态压缩DP
- K-Means聚类算法的原理及实现【转】 【转】
- 雪碧图最佳实践
- 大神揭秘:苹果 ARKit 凭什么碾压对手?
- 【机器学习笔记之五】用ARIMA模型做需求预测用ARIMA模型做需求预测
- $.fn.extend 与$.extend 的区别
- HDU 4529 状态压缩DP
- ajax中的contentType和dataType
- 居然突然忘了怎么转格式,看来不能总是复制呀
- JAVA中Map接口的常用方法
- 1023. 组个最小数 (20)
- ReactNative +jenkins +svn 集成打包
- iOS App 启动性能优化
- [HAOI2016]食物链
- 正则表达式简介及学习网址、测试网址