首页 > 代码库 > UVa 10651 - Pebble Solitaire
UVa 10651 - Pebble Solitaire
题目:有一个类似跳棋的游戏,一共有12个位置‘o‘代表棋子‘-‘代表空位,
‘oo-‘可以转化成‘--o‘,‘-oo‘可以转化成‘o--‘,给你初始状态,问最后,至少剩下几个棋子。
分析:dp,记忆化搜索,位运算。利用搜索在相邻状态间dp即可。
每个状态的最优解为他能转化所有状态中的最优解。
因为,一共有2^12 = 4096个状态,每次找到解即存储,不会重复计算,所以时间方面没问题。
利用一个12位整数表示一个状态,‘o‘用1表示,‘-‘用0表示,则’---oo-------‘为24(2进制000000011000)
(这里是从左向右代表低位到高位,倒过来也可以)
通过观察可以发现‘oo-‘(011)转化成‘--o‘(100),‘-oo‘(110)转化成‘o--‘(001)都是对应为取反;
直接利用7(2进制111)进行异或即可,而对应额可以跳的状态为3(2进制011)与6(2进制110);
说明:详细参考代码。
#include <algorithm> #include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> #include <cstdio> #include <cmath> using namespace std; char buf[13]; int F[4100]; int dfs(int s) { if (F[s] < 13) return F[s]; int Min = 12; for (int i = 0 ; i < 10 ; ++ i) if (((s>>i)&7) == 3 || ((s>>i)&7) == 6) Min = min(Min, dfs(s^(7<<i))); if (Min == 12) { for (int i = 0 ; i < 12 ; ++ i) Min -= !(s&(1<<i)); } return F[s] = Min; } int main() { for (int i = 0 ; i < 4100 ; ++ i) F[i] = 13; int n,v; while (~scanf("%d",&n)) for (int i = 1 ; i <= n ; ++ i) { scanf("%s",buf); v = 0; for (int j = 0 ; j < 12 ; ++ j) { v <<= 1; if (buf[j] == 'o') v += 1; } printf("%d\n",dfs(v)); } return 0; }
UVa 10651 - Pebble Solitaire
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。