蜘蛛牌 HDU - 1584(搜索——达到先让某些段先结合,达最优解)
題意:
一排雜亂的牌,牌間距為1,每次移動只能將小的牌,移動到較大牌上,最終使得牌從小到大排好在一堆。問移動的最小距離。
題目:
蜘蛛牌是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.對移動牌的先后順序進行枚舉(全排列,當然要剪枝)
2.其實這道題很簡單,但由于我忽略了,break導致錯誤,所以我來總結下此類搜索題的做法:找某種最優情況,(1)若為圖一般用記憶化搜索(2)若為線性結構就基本上是全排列將所有情況排列出來,找出最優解。由于復雜度比較大,所以剪枝是比較重要的。
3 對本題來說,我們只能將較小牌放到較大牌上,若最優一定是某些段先結合最終得到一堆。所以類似全排列,若最優只能讓較小牌到達離他最近的沒有標記過的較大牌,故找到后需跳出循環。得到使某些段先結合的效果。
4 全排列的搜索模板
AC代碼
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; const int inf=0x3f3f3f; int a[20],ans,book[20]; void dfs(int step,int num) {if(step==9){ans=num;return ;}for(int i=1; i<10; i++)if(!book[i]){book[i]=1;for(int j=i+1; j<=10; j++)if(!book[j]&&abs(a[j]-a[i])+num<ans){dfs(step+1,num+abs(a[i]-a[j]));break;/*從位置i走到j只能是i到沒有標記過的第一個j(在遞歸過程中實現中間的某一段結合,再從頭到尾結合)*/}book[i]=0;}return ; } int main() {int t;scanf("%d",&t);while(t--){for(int i=1; i<=10; i++){int c;scanf("%d",&c);a[c]=i;}ans=inf;memset(book,0,sizeof(book));dfs(0,0);printf("%d\n",ans);}return 0; }總結
以上是生活随笔為你收集整理的蜘蛛牌 HDU - 1584(搜索——达到先让某些段先结合,达最优解)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 劲酒加红牛有什么功能
- 下一篇: 什么是海绵肾