码迷,mamicode.com
首页 > 其他好文 > 详细

UVa 10651 - Pebble Solitaire

时间:2014-12-02 06:47:07      阅读:235      评论:0      收藏:0      [点我收藏+]

标签:io   ar   os   sp   for   问题   bs   代码   amp   

题目:有一个类似跳棋的游戏,一共有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

标签:io   ar   os   sp   for   问题   bs   代码   amp   

原文地址:http://blog.csdn.net/mobius_strip/article/details/41665351

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!