UVA11212Editing aBook 编辑书稿
生活随笔
收集整理的這篇文章主要介紹了
UVA11212Editing aBook 编辑书稿
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
問題描述:你有一篇由n(n[2,9])個自然段組成的文章,希望將它們排列成1,2,、、、n。可以用Crtl+X和Ctrl+V快捷鍵來完成任務。每次可以剪一段連續的自然段,粘貼時按照順序粘貼。注意,剪貼板只有一個,所以不能連續剪切兩次,只能剪切和粘貼交替。
例如,為了將{2,4,1,5,3,6}變為升序,可以剪切1將其放到2前,然后剪切3將其放到4前,再如,對于排列{3,4,5,1,2},只需要剪切一次和粘貼一次即可——將{3,4,5}放在{1,2}后面或者{1,2}放在{3,4,5}前面。
分析:對于長度n為9時,最多移動8次即可,而實驗得知長度為9,{9,8,7,6,5,4,3,2,1},最多移動5次。所以枚舉移動上限為5。然后有一個最重要的剪枝,3d+h>3*maxd,d是目前移動的次數,也就是深度,而h是錯誤段落的個數,maxd是最大深度。可知每次移動最多會有3個段落次序發生改變,所以當錯誤段落個數大于剩余的移動次數*3的時候剪枝。
#include<cstdio> #include<cstring> #include<cctype> #include<queue> #include<iostream> #include<vector> using namespace std; const int maxn = 100 + 5; int a[maxn]; int n = 0; int h() {int cnt = 0;for (int i = 0; i < n - 1; i++)if (a[i] +1!= a[i + 1])cnt++;if (a[n - 1] != n)cnt++;return cnt; } bool is_sorted() {for (int i = 0; i < n - 1; i++)if (a[i] >= a[i + 1])return false;return true; } bool dfs(int d,int maxd) {if (3 * d + h() > 3 * maxd)return false;if (is_sorted())return true;int old[maxn], b[maxn];memcpy(old, a, sizeof(a));for (int i = 0; i < n; i++) {for (int j = i; j < n; j++) {int cnt = 0;for (int k = 0; k < n; k++)if (k<i || k>j)b[cnt++] = a[k];//取出不移動的位置for (int k = 0; k < cnt; k++) {//枚舉剩余可移動位置(不移動的元素個數)int cnt2 = 0;for (int p = 0; p < k; p++)a[cnt2++] = b[p];//移動到這個位置for (int p = i; p <= j; p++)a[cnt2++] = old[p];for (int p = k; p < cnt; p++)a[cnt2++] = b[p];if (dfs(d + 1, maxd))return true;memcpy(a, old, sizeof(a));//回溯要還原}}}return false; } int solve() {if (is_sorted())return 0;int max_ans = 5;for (int maxd = 1; maxd < max_ans; maxd++) {if (dfs(0, maxd))return maxd;}return max_ans; } int main() {int kase=0;while (cin >> n &&n) {int temp;for (int i = 0; i < n; i++) { cin >> a[i]; }cout << "Case " << ++kase << ": ";cout << solve() << endl;}return 0; }?
總結
以上是生活随笔為你收集整理的UVA11212Editing aBook 编辑书稿的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 埃及分数问题——迭代加深搜索
- 下一篇: UVA12325Zombie's Tre