1. 程式人生 > >Uva 11212 編輯書稿(叠代加深搜索)

Uva 11212 編輯書稿(叠代加深搜索)

blog 互換 clas () 就是 當前 叠代加深搜索 const 對稱

題意:

給定N個數的序列, 希望將它排列成1~N, 可以用剪切、粘貼來完成任務, 每次可以剪切一段連續的自然段, 粘貼時按照順序粘貼。

#include <bits/stdc++.h>
#define rep(i,a,b) for(int i = a; i < b; i++)
#define _rep(i,a,b) for(int i = a; i <= b; i++)
using namespace std;
const int maxn = 12;
int n, maxd;
int p[maxn], ans;
int h(){//統計每個元素後繼不符合的個數, 最後一個特判是否為N
int cnt = 0; rep(i,0,n-1) if(p[i+1] != p[i] + 1) cnt++; if(p[n-1] != n) cnt++; return cnt; } bool dfs(int d){ if(d*3 + h() > maxd*3) return false; //由於每次交換最多減少3個後繼不符合, 所以當前層數*3 + 上h()大於maxd * 3, 直接剪枝 if(d == maxd){ if(h() == 0) return true; return false; }
int b[maxn], old[maxn], cnt = 0; memcpy(old,p,sizeof(p)); rep(i,0,n) //選擇起點 rep(j,i,n) //選擇終點 , p上取 3個點, i , j , k rep(k,j+1,n){ //由於具有對稱性, 直接把前面換到後面就行 memcpy(b,old+i,sizeof(int) * (j-i+1)); //將i~j剪貼的內容復制到b memcpy(p+i,old+j+1, sizeof(int) * (k-j));//將i~j 與 (j+1)~k互換 memcpy(p+i+k-j, b, sizeof
(int) * (j-i+1)); if(dfs(d+1)) return true; memcpy(p,old,sizeof(old)); } return false; } int main(){ int kase = 0; while(cin >> n && n){ rep(i,0,n) cin >> p[i]; for(maxd = 0; maxd <= 5; maxd++){ //註意maxd要從0開始, 因為有可能一開始就是有序的 if(dfs(0)) break; } cout << "Case " << ++kase << ": " << maxd << "\n"; } }

Uva 11212 編輯書稿(叠代加深搜索)