D - 蜘蛛牌

Time Limit:5000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

Description

蜘 蛛牌是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
 就是一个简单的DFS,但是要弄清楚牌的先后顺序:比如说我现在要排3,首先考虑4,如果4没排,就放到4下面,如果已经排了6,5,4;那么离4最近的是6(6没排)
再就是有一个剪枝: if(sum>ans) return;   如果还没排完就发现比上次排完的ans大,直接退出(回溯)
然后最难以理解的就是如何回溯,在哪里回溯:因为是在枚举i,排列i.所以在i的for循环里回溯:vis[i]=0;
DFS(t+1,sum+abs(dis[j]-dis[i])); 26 break;
 1 #include<cstdio>

 2 #include<string.h>

 3 #include<math.h>

 4 using namespace std;

 5 int vis[15],dis[15];//标记数组和位置数组

 6 int ans;

 7 void DFS(int t,int sum)

 8 {

 9     if(sum>ans) return;

10     if(t==9)

11     {

12         ans=ans<sum?ans:sum;

13         return;

14     }

15 

16     for(int i=1; i<=9; i++)//枚举要排的数

17     {

18         if(!vis[i])

19         {

20             vis[i]=1;

21             for(int j=i+1; j<=10; j++)

22             {

23                if(!vis[j])

24                {

25                    DFS(t+1,sum+abs(dis[j]-dis[i]));

26                    break;

27                }

28 

29             }

30             vis[i]=0;

31         }

32     }

33 }

34 

35 int main()

36 {

37     int t;

38     scanf("%d",&t);

39     while(t--)

40     {

41         int x;

42         memset(vis,0,sizeof(vis));

43         for(int i=1;i<=10;i++)

44         {

45             scanf("%d",&x);

46             dis[x]=i;

47         }

48         ans=1000000000;

49         DFS(0,0);

50         printf("%d\n",ans);

51     }

52     return 0;

53 }

 

你可能感兴趣的:(D - 蜘蛛牌)