HDU1584(分治法)

蜘蛛牌

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


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
 
 
//此题符合分治法的基本思想,将问题分解为[1,k]和[k+1,10]两个子问题,然后将其合并即加上将[1,k]整体移到[k+1,10]后面的损耗!

#include<iostream> #include<cmath> using namespace std;

int ind[11]; int tran[11][11];

int cal(int a,int b) {  int ans=1<<30,i,temp;  if(abs(a-b)<=1)   return tran[a][b];  for(i=a;i<b;i++)  {   temp=cal(a,i)+cal(i+1,b)+tran[i][b];   if(temp<ans) ans=temp;  }  return ans; }

int main() {   int i,n,t,tmp,j;  cin>>t;  while(t--)  {   for(i=0;i<10;i++)   {    scanf("%d",&tmp);    ind[tmp]=i;   }   for(i=1;i<=10;i++)   {    for(j=1;j<=10;j++)    {     tran[i][j]=abs(ind[i]-ind[j]);    }   }   cout<<cal(1,10)<<endl;  }  return 0; }

你可能感兴趣的:(分治)