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 }

 

posted on 2014-08-07 13:21  Damonll  阅读(182)  评论(0编辑  收藏  举报