LightOJ 1061N Queen Again(搜索+状压DP)
来源:互联网 发布:linux简单管道 编辑:程序博客网 时间:2024/06/05 02:38
题目
给出一张8*8的图,上面有8个皇后,现在每次只能移动一个皇后往同一个方向走任意步,总共有8个方向;问最少需要多少步使得所有皇后相互不会攻击对方?
思路
单纯的暴搜是不行的,时空都会炸。
假如我们知道最终每个皇后应该在的位置,然后再来计算最少步数就会简单不少,这里可以用状压来做;
因为最终的情况是每行有一个皇后,所以我没需要记录每行皇后所在的列,然后枚举哪个皇后移动到这个位置来;
dp[sta][row],表示考虑第row行的皇后来源时的状态为sta,然后我们尝试把sta & (1 << i ) == 1,即原图中第i个皇后移动到row行对应皇后的位置去;这里的总的复杂度为8∗28 ;
然后我们就是要找出所有合法的情况,搜索一下就发现有92种合法情况;
最后就是对每种情况跑一遍状压,取所有情况的最小值;
题目中有说两个皇后不能同时出现在一个格子里面,在移动过程中会出现相遇的情况;但是通过不同移动的先后顺序是可以避免相遇的情况的;
int p[110][10]; // p[cnt][row] = col;第cnt张图的第row行的Queen在col列int tp[10]; // tp[row] = col;当前图的row行的Queen在col列int dp[1 << 9][10]; // dp[sta][row];int x[10], y[10]; // the position of eight queen;int cnt;void dfs(int row) { if (row == 8) { for (int i = 0;i < 8;++i) p[cnt][i] = tp[i]; ++cnt; return ; } // 枚举第row行的Queen在col列,再判断可行性 for (int col = 0;col < 8;++col) { bool ok = true; for (int i = 0;i < row;++i) { if (col == tp[i] || tp[i] + i == row + col || tp[i] - i == col - row) { ok = false; break; } } if (ok){ tp[row] = col; dfs(row + 1); } }}int getdis(int cur, int num, int i) { //这儿abs很重要 int t1 = abs(x[i] - num); int t2 = abs(y[i] - p[cur][num]); int res = 0; if (min(t1, t2) != 0) res++; if (abs(t1 - t2) != 0) res++; return res;}int go(int cur, int num, int sta) { if (num == 0) return 0; if (dp[sta][num] != -1) return dp[sta][num]; int tans = inf; for (int i = 0;i < 8;++i) { if (sta & (1 << i)) { // 对于第cur张图而言,把第i个Queen放在这张图第(num - 1)行Queen所在的位置 tans = min(tans, getdis(cur, num - 1, i) + go(cur, num - 1, sta ^ (1 << i)) ); } } return dp[sta][num] = tans;}int solve() { int ans = inf; for (int i = 0;i < cnt;++i) { memset(dp, -1, sizeof dp); ans = min(ans, go(i, 8, (1 << 8) - 1)); } return ans;}int main(int argc, const char * argv[]){ dfs(0); int kase;cin >> kase; while(kase--) { int t = 0; for (int i = 0;i < 8;++i) { char s[10];scanf("%s", s); for (int j = 0;j < 8;++j) { if (s[j] == 'q') { x[t] = i; y[t] = j; ++t; } } } int ans = solve(); printf("Case %d: %d\n", ++nCase, ans); } return 0;}
0 0
- LightOJ 1061N Queen Again(搜索+状压DP)
- LightOJ 1061 N Queen Again(状压DP)
- LightOJ 1061 1061 - N Queen Again(状压dp)
- LightOJ - 1061 N Queen Again(状压DP)
- lightoj1061 (N Queen Again)搜索+状压dp
- lightoj 1061 - N Queen Again
- Light OJ 1061 - N Queen Again(搜索+状压DP)
- Light OJ 1061 N Queen Again
- LightOJ 1038 - Race to 1 Again(dp)
- LightOJ 1038 - Race to 1 Again (期望dp)
- LightOJ-1038-Race to 1 Again(概率dp)
- Lightoj 1036 DP(记忆化搜索)
- Lightoj 1084 记忆化搜索(DP)
- N-Queen(java实现)
- LightOJ 1038 - Race to 1 Again 【DP】
- N queen
- N-queen
- N-Queen
- angular实现的面板组件
- Unity下XLua方案的各值类型GC优化深度剖析
- java第十八天
- linux 内核同步
- java第十五天-总结1
- LightOJ 1061N Queen Again(搜索+状压DP)
- Crackme 4
- 浅谈retrofit2.1+okhttp3 搭建MVP框架
- java第十六天-异常体系
- 排序面试指南
- Android热修复技术选型——三大流派解析
- 防止刷票的一些方法介绍
- java.util.MissingFormatArgumentException: Format specifier 'd'
- 前端工程师不得不知道的ES6新特性(四)