HDU

先上题目:

蜘蛛牌

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1303    Accepted Submission(s): 512


Problem 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
 
 
  搜索题,题意中文不解释,一开始想到用bfs,结果爆内存了= =,后来在网上看了一下别人的做法= =。大概如下:
  首先需要分析,这个游戏操作上的特点:
  ①一定是小牌往大牌上移动。
  ②可能把不同的牌当成小牌作为开始移动的第一张
  ③有很多种移动的顺序,但是我们要找的是总距离最小的一种,所以我们要枚举,但是也要剪枝
  ④在枚举过程中遇到距离大于记录的最小距离的时候可以直接剪去。
  总的来说还是对dfs的题目不是很熟练······
 
上代码:
 1 #include <cstdio>
 2 #include <cmath>
 3 #include <cstring>
 4 #include <queue>
 5 #define MAX 11
 6 #define INF 100000000
 7 using namespace std;
 8 
 9 int loc[MAX];
10 bool vis[MAX];
11 int dist;
12 
13 void dfs(int cns,int temp){
14     if(temp>=dist) return ;
15     if(cns==9){
16         dist=temp;
17         return;
18     }
19     for(int i=1;i<=10;i++){
20         if(!vis[i]){
21             for(int j=i+1;j<=10;j++){
22                     if(!vis[j]){
23                         vis[i]=1;
24                         dfs(cns+1,temp+abs(loc[i]-loc[j]));
25                         break;
26                     }
27             }
28             vis[i]=0;
29         }
30     }
31 }
32 
33 int main()
34 {
35     int t;
36     //freopen("data.txt","r",stdin);
37     scanf("%d",&t);
38     while(t--){
39         int n;
40         for(int i=1;i<=10;i++){
41             scanf("%d",&n);
42             loc[n]=i;
43         }
44         dist=INF;
45         memset(vis,0,sizeof(vis));
46         dfs(0,0);
47         printf("%d
",dist);
48     }
49     return 0;
50 }
1584
原文地址:https://www.cnblogs.com/sineatos/p/3515324.html