状态压缩DP POJ 1321 棋盘问题
来源:互联网 发布:淘宝卖衣服代理 编辑:程序博客网 时间:2024/06/01 09:22
题目:
Description
在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。
Input
输入含有多组测试数据。
每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目。 n <= 8 , k <= n
当为-1 -1时表示输入结束。
随后的n行描述了棋盘的形状:每行有n个字符,其中 # 表示棋盘区域, . 表示空白区域(数据保证不出现多余的空白行或者空白列)。
每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目。 n <= 8 , k <= n
当为-1 -1时表示输入结束。
随后的n行描述了棋盘的形状:每行有n个字符,其中 # 表示棋盘区域, . 表示空白区域(数据保证不出现多余的空白行或者空白列)。
Output
对于每一组数据,给出一行输出,输出摆放的方案数目C (数据保证C<2^31)。
Sample Input
2 1#..#4 4...#..#..#..#...-1 -1
Sample Output
21
情不自禁的想起来,以前自己玩游戏,遇到计算量特别大的关卡,玩不过去,可以编程解决的就会编程解决。
最变态的时候写过22层的循环,因为问题那个游戏真的好难好难。。。
于是我写了一个8层的循环。。。。
代码:
#include<iostream>#include<string.h>using namespace std;int list[8];//输入的棋盘状态char c;int sum;int result;//最后的结果int main(){int n, k;while (cin >> n >> k){if (n == -1)break;memset(list, 0, sizeof(list));result = 0;for (int i = 0; i < n; i++){for (int j = 0; j < n; j++){cin >> c;if (c == '#')list[i] += (1 << j);}}for (int i7 = 0; i7 < (1 << n); i7++)//8层循环,要注意顺序,因为如果n<7的话i7只能是0{if (i7 != (i7&(-i7)))continue;if ((i7&list[7]) != i7)continue;for (int i6 = 0; i6 < (1 << n); i6++){if (i6 != (i6&(-i6)))continue;//1行只能放1个if ((i6&list[6]) != i6)continue;//只能放在写了'#'的格子里面if (i6&i7)continue;//1列只能放1个for (int i5 = 0; i5 < (1 << n); i5++){if (i5 != (i5&(-i5)))continue;if ((i5&list[5]) != i5)continue;if (i5&(i6 | i7))continue;for (int i4 = 0; i4 < (1 << n); i4++){if (i4 != (i4&(-i4)))continue;if ((i4&list[4]) != i4)continue;if (i4&(i5 | i6 | i7))continue;for (int i3 = 0; i3 < (1 << n); i3++){if (i3 != (i3&(-i3)))continue;if ((i3&list[3]) != i3)continue;if (i3&(i4 | i5 | i6 | i7))continue;for (int i2 = 0; i2 < (1 << n); i2++){if (i2 != (i2&(-i2)))continue;if ((i2&list[2]) != i2)continue;if (i2&(i3 | i4 | i5 | i6 | i7))continue;for (int i1 = 0; i1 < (1 << n); i1++){if (i1 != (i1&(-i1)))continue;if ((i1&list[1]) != i1)continue;if (i1&(i2 | i3 | i4 | i5 | i6 | i7))continue;for (int i0 = 0; i0 < (1 << n); i0++){if (i0 != (i0&(-i0)))continue;if ((i0&list[0]) != i0)continue;if (i0&(i1 | i2 | i3 | i4 | i5 | i6 | i7))continue;sum = 0;if (i0)sum++;//整个棋盘放了多少个棋子if (i1)sum++;if (i2)sum++;if (i3)sum++;if (i4)sum++;if (i5)sum++;if (i6)sum++;if (i7)sum++;if (sum == k)result++;}}}}}}}}cout << result << endl}
return 0;
}
(为了把这个代码弄的这么好看,我也是拼了。。。)
很显然,这个方法是很慢很慢的(虽然我AC了,但是这肯定是不行的)
于是我又写了新的代码:
#include<iostream>#include<string.h>using namespace std;int list[8];//输入的棋盘状态int r[8][256];char c;int sum;int k;bool ok(int n){int s = 0;for (int a = 1; a < 256; a *= 2)if (n & a)s++;if (s>k)return false;return true;}int main(){int n;while (cin >> n >> k){if (n == -1)break;memset(list, 0, sizeof(list));memset(r, 0, sizeof(r));for (int i = 0; i < n; i++)//输入{for (int j = 0; j < n; j++){cin >> c;if (c == '#')list[i] += (1 << j);}}for (int i = 0; i < (1 << n); i++)
if ((i&list[0]) == i && ok(i)&&(i&(-i))==i)r[0][i] = 1;for (int i = 1; i < n; i++)for (int j = 0; j < (1 << n); j++)
if (ok(j))for (int kk = 0; kk < (1 << n); kk++)
if ((j&kk) == kk && ((j^kk)&list[i]) == (j^kk) && ((j^kk)&(-(j^kk))) == (j^kk))
r[i][j] += r[i - 1][kk];sum = 0;for (int i = 0; i < (1 << n); i++){int s = 0;for (int a = 1; a < 256; a *= 2)if (i & a)s++;if(s==k)sum += r[n - 1][i];}cout << sum << endl;}return 0;}
主要就是r
r[i][j] 表示的是前i行的状态是 j 的情况数。
比如说,i=4,j=1011,那么前4行的状态是第1,2,4个被取了。(之所以用这样的顺序是因为维度是不确定的,这样方便很多)
可能是第1行取1,第2行取2,第4行取4,
也有可能是第1行取2,第2行取4,第4行取1,等等。。。
1 0
- 状态压缩DP POJ 1321 棋盘问题
- poj 1321 状态压缩dp-棋盘问题
- POJ 1321 棋盘问题 DFS 和 状态压缩DP
- poj-1321 棋盘问题(状态压缩)
- POJ 1321 棋盘问题 状态压缩入门
- poj1321 棋盘问题,状态压缩dp
- 状态压缩动态规划 -- 棋盘问题 POJ 1321
- 棋盘问题---状态压缩
- poj 2288(状态压缩dp + TSP问题)
- POJ 1321 经典棋盘问题 的搜索和状态压缩解法
- poj 1321 棋盘问题 状压dp
- 棋盘放车(DP状态压缩)
- poj 1321 状态压缩dp||dfs
- poj 1038 状态压缩~棋盘覆盖
- 【状态压缩DP】POJ 1170
- 【状态压缩DP】POJ 1185
- POJ 3254 状态压缩DP
- poj 3254 状态压缩dp
- C++中智能指针的设计和使用
- 《primer-c++4》学习笔记-第exercise9.38
- [ERROR] Event Scheduler: Failed to open table mysql.event
- MySQL锁解决并发问题详解
- App 研发录 阅读笔记 (6-9)(附代码)
- 状态压缩DP POJ 1321 棋盘问题
- Ubuntu14.04+Beanstalkd1.9+Golang最佳实践
- C++11 并发编程教程 - Part 3 : 锁的进阶与条件变量
- spring mvc常用注解@Component @Controller @Service @Repository
- SQL Server死锁总结
- Spring 中有用的配置
- python threadpool 多参数处理
- wget -个网站以便脱机浏览
- UITableViewCell 分割线顶格