UVA11212-Editing a Book(迭代加深搜索)

Problem UVA11212-Editing a Bookios

Accept:572  Submit:4428

Time Limit: 10000 mSec

 Problem Description

 

You have n equal-length paragraphs numbered 1 to n. Now you want to arrange them in the order of 1,2,...,n. With the help of a clipboard, you can easily do this: Ctrl-X (cut) and Ctrl-V (paste) several times. You cannot cut twice before pasting, but you can cut several contiguous paragraphs at the same time - they’ll be pasted in order. For example, in order to make {2, 4, 1, 5, 3, 6}, you can cut 1 and paste before 2, then cut 3 and paste before 4. As another example, one copy and paste is enough for {3, 4, 5, 1, 2}. There are two ways to do so: cut {3, 4, 5} and paste after {1, 2}, or cut {1, 2} and paste before {3, 4, 5}.算法

 Input

The input consists of at most 20 test cases. Each case begins with a line containing a single integer n (1 < n < 10), thenumber of paragraphs. The next line contains a permutation of 1,2,3,...,n. The last case is followed by a single zero, which should not be processed.框架

 

 Output

For each test case, print the case number and the minimal number of cut/paste operations.函數

 

 Sample Input

6
2 4 1 5 3 6
5
3 4 5 1 2
0
 

 Sample Ouput

Case 1: 2 this

Case 2: 1spa

 

題解:第一到IDA*算法的題目。迭代加深搜索,就是在普通DFS上加了個深度限制,若是目前的深度沒法獲得結果,就讓深度限制變大,直到找到解。該算法中最重要的就是估價函數,用該函數進行剪枝操做,當前深度爲d,若是最理想的狀況下還要搜索h層,那麼當d+h > maxd時顯然就能夠剪枝,其他部分和普通dfs區別不大。code

續:今天對這道題又進行了一個小小的嘗試,收穫很大。之因此對它進行二次嘗試,主要是由於第一次寫時按照lrj的思路copy的,想真正本身實現一次,此次實現徹底以lrj在講解該算法時的思路爲框架進行code,dfs第一步判斷深度是否達到maxd,達到了就進行判斷是否成立,返回信息。關鍵在於下一步的是先枚舉仍是先剪枝,若是先剪枝,兩個代碼的效率幾乎沒有差距,若是先枚舉,直接TLE,這份代碼用時640ms而限制是10000ms,這一個順序使得效率差了十倍不止,仔細想了想,先剪枝與後剪枝相比,把剪枝操做提早了一層,對於每一層都有不少節點的搜索來講是很不划算的。千萬注意這個順序!!!blog

 

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <algorithm>
 6 
 7 using namespace std;  8 
 9 const int maxn = 9; 10 int n,order[maxn]; 11 int maxd; 12 
13 int cal() { 14     int cnt = 0; 15     for (int i = 0; i < n-1; i++) { 16         if (order[i] != order[i + 1] - 1) cnt++; 17  } 18     if (order[n - 1] != n) cnt++; 19     return cnt; 20 } 21 
22 bool is_sorted() { 23     for (int i = 0; i < n - 1; i++) { 24         if (order[i] >= order[i + 1]) return false; 25  } 26     return true; 27 } 28 
29 bool dfs(int d) { 30     if (3 * d + cal() > maxd * 3) return false; 31     if (is_sorted()) return true; 32 
33     int old[maxn],now[maxn]; 34     memcpy(old, order, sizeof(order)); 35     for (int i = 0; i < n; i++) { 36         for (int j = i; j < n; j++) { 37             int cnt = 0; 38             for (int k = 0; k < n; k++) { 39                 if (k < i || k > j) { 40                     now[cnt++] = order[k]; 41  } 42  } 43             for (int k = 0; k <= cnt; k++) { 44                 int cnt2 = 0; 45                 for (int p = 0; p < k; p++) order[cnt2++] = now[p]; 46                 for (int p = i; p <= j; p++) order[cnt2++] = old[p]; 47                 for (int p = k; p < cnt; p++) order[cnt2++] = now[p]; 48                 if (dfs(d + 1)) return true; 49                 memcpy(order, old, sizeof(order)); 50  } 51  } 52  } 53     return false; 54 } 55 
56 int iCase = 1; 57 
58 int main() 59 { 60     //freopen("input.txt", "r", stdin);
61     while (~scanf("%d", &n) && n) { 62         for (int i = 0; i < n; i++) { 63             scanf("%d", &order[i]); 64  } 65         for (maxd = 0; maxd < n; maxd++) { 66             if (dfs(0)) break; 67  } 68         printf("Case %d: %d\n", iCase++, maxd); 69  } 70     return 0; 71 }
相關文章
相關標籤/搜索