uva10651 - Pebble Solitaire(记忆化搜索)

来源:互联网 发布:美国js眼部精华霜 编辑:程序博客网 时间:2024/05/21 11:07

题目:uva10651 - Pebble Solitaire(记忆化搜索)


题目大意:12个坑,每个坑里面可以放卵石,也可以不放。然后如果出现00- 或是 -00这样的情况,就可以变成--0和0--。给定初始的状态问最总剩余的卵石个数。

解题思路:这里只有12的位置,并且每个位置只有两种可能,所以可以用二进制数来表示所有的状态。判断卵石的情况每次都是3个3个判断,发现能够转换,就变换成另一个状态直到不能转换为止。因为每个状态最后剩下的卵石是确定的。所以可以用记忆化搜索,之前查找过的状态要将值记录下来,这样下次查找的时候就不用在做一次。这样之前的dp数组就要有一个初始值代表还没有访问过,并且因为这里是要取最小值,所以这里的初始值可以放13.

           二进制操作 :

                               n & (1<<i) 代表取出第i位的值, n | (1<<i) 把第i位变成1, n & (~(1 <<i)) 把第i位变成0。

代码:

#include <cstdio>#include <cstring>const int N = 12;const int maxn = 1 << N;int dp[maxn];void init () {for (int i = 0; i < maxn; i++)dp[i] = N + 1;}int Min (const int a, const int b) { return a < b ? a: b; }int d (int n) {if (dp[n] != N + 1)return dp[n];int t;for (int i = 0; i < N - 2; i++) { t = n;if ((n & (1 << i)) && (n & (1 << (i + 1))) && ! (n & (1 << (i + 2)))) {  t &= ~(1 << i);  t &= ~(1 << (i + 1));  t |= 1 << (i + 2);  dp[n] = Min (dp[n] , dp[t] = Min (dp[t], d(t)));} else if (!(n & (1 << i)) && (n & (1 << (i + 1))) && (n & (1 << (i  + 2)))) {  t |= 1 << i;  t &= ~(1 << (i + 1));  t &= ~(1 << (i + 2));  dp[n] = Min (dp[n], dp[t] = Min (dp[t], d(t)));}}int cnt = 0;for (int i = 0; i < N; i++)if (n & (1 << i))cnt++;return dp[n] = Min(dp[n], cnt);}int main () {int t;int n;char ch;scanf ("%d%*c", &t);init ();while (t--) {n = 0;for (int i = 0; i < N; i++) {scanf ("%c", &ch); if (ch == 'o')n = n | (1 << i);}getchar();printf ("%d\n", d(n));}return 0;}



0 0
原创粉丝点击