蜘蛛牌 HDU - 1584

蜘蛛牌

 
蜘蛛牌是windows xp操作系统自带的一款纸牌游戏,游戏规则是这样的:只能将牌拖到比她大一的牌上面(A最小,K最大),如果拖动的牌上有按顺序排好的牌时,那么这些牌也跟着一起移动,游戏的目的是将所有的牌按同一花色从小到大排好,为了简单起见,我们的游戏只有同一花色的10张牌,从A到10,且随机的在一行上展开,编号从1到10,把第i号上的牌移到第j号牌上,移动距离为abs(i-j),现在你要做的是求出完成游戏的最小移动距离。 
Input第一个输入数据是T,表示数据的组数。 
每组数据有一行,10个输入数据,数据的范围是[1,10],分别表示A到10,我们保证每组数据都是合法的。Output对应每组数据输出最小移动距离。Sample Input
1
1 2 3 4 5 6 7 8 9 10
Sample Output
9
题解+解析:
#include <cstdio>  
#include <algorithm>  
#include <cstring>  
#include <iostream>  
#include <cstdlib>  

using namespace std;  
int a[15];
bool visit[15];
int ans;
void dfs(int num, int sum)  
{  
	if (sum >= ans)
	{
		return; // 不是最优,剪枝。
	}
	if (num == 9)//移9次说明已经完成排列了。
	{
		ans = sum;
	}
	for (int i = 1; i < 10; i++)//确定需要移的数i。
	{
		if (!visit[i])
		{
			visit[i] = true;//i被移走了,所以数字i的位置设为被访问过,也就是说该位置没有数字。
			for (int j = i+1; j < 11; j++)//确定被移到的数j(j至少比i大1)。也有可能j比i大很多,例如把1移到5的下面。1没有访问过,2,3,4却访问过,说明2,3,4都在5的下面,所以可以把1移到5的下面。
			{
				if (!visit[j])
				{
					dfs(num+1, sum+abs(a[i]- a[j]));//操作数等于位置差的绝对值。
					break;
				}
			}
			visit[i] = false;//回溯到i没有被移走的状态。
		}
	} 
}  

int main()
{
	int n;
	scanf("%d", &n);
	while (n--)
	{
		ans = 0x7f7f7f7f;
		memset(visit, 0, sizeof(visit));
		for (int i = 1; i <= 10 ;i++)
		{
			int temp;
			scanf("%d", &temp);
			a[temp] = i;//确定temp这个数在第i个位置
		}
		dfs(0, 0);
		printf("%d\n", ans);
	}
	return 0;
}



posted @ 2018-04-11 21:12  focus5679  阅读(131)  评论(0编辑  收藏  举报