https://www.lydsy.com/JudgeOnline/problem.php?id=5449
话说很早以前做过。。算是IDA*的板子吧,一个简单的估价函数就可以过去了
1 %:pragma GCC optimize(2) 2 #include<cstdio> 3 #include<algorithm> 4 using namespace std; 5 int a[50],n,maxd,T; 6 bool fl; 7 inline bool check() 8 { 9 for(int i=1;i<n;++i) 10 if(a[i]>a[i+1]) 11 return 0; 12 return 1; 13 } 14 //reverse一次,相邻两数绝对值之差大于1的最多减少1个, 15 //因此相邻两数绝对值之差大于1的个数一定小于等于所需reverse次数 16 inline int hh() 17 { 18 int cnt=0; 19 for(int i=1;i<n;++i) 20 if(abs(a[i+1]-a[i])>1) 21 cnt++; 22 return cnt; 23 } 24 inline void reverse1(const int& r) 25 { 26 int i,t; 27 for(i=1;i<=r/2;++i) 28 { 29 t=a[i];a[i]=a[r-i+1];a[r-i+1]=t; 30 } 31 } 32 void dfs(int x,int last) 33 { 34 if(fl) return; 35 if(x==maxd) 36 { 37 if(check()) fl=1; 38 return; 39 } 40 if(x+hh()>maxd) return; 41 for(int i=2;i<=n;++i) 42 if(i!=last) 43 { 44 reverse(a+1,a+i+1); 45 dfs(x+1,i); 46 reverse(a+1,a+i+1); 47 } 48 } 49 int main() 50 { 51 int i; 52 scanf("%d",&T); 53 while(T--) 54 { 55 fl=0; 56 scanf("%d",&n); 57 for(i=1;i<=n;++i) 58 scanf("%d",&a[i]); 59 for(maxd=0;maxd<=30;++maxd) 60 { 61 dfs(0,0); 62 if(fl) break; 63 } 64 printf("%d ",maxd); 65 } 66 return 0; 67 }
此题http://210.33.19.103/contest/823/problem/2(序列)同以上题
upd20190222:
根据网上一些高分程序优化了一下估价函数和代码...
1 %:pragma GCC optimize(2) 2 #include<cstdio> 3 #include<algorithm> 4 using namespace std; 5 int a[50],n,maxd,T; 6 bool fl; 7 inline int abs1(int x){return x>0?x:-x;} 8 inline int hh() 9 { 10 int cnt=(a[n]!=n); 11 for(int i=1;i<n;++i) 12 if(abs1(a[i+1]-a[i])>1) 13 ++cnt; 14 return cnt; 15 } 16 void dfs(int x,int last) 17 { 18 int h=hh(); 19 if(!h) {fl=1;return;} 20 if(x+h>maxd) return; 21 for(int i=2;i<=n;++i) 22 if(i!=last) 23 { 24 reverse(a+1,a+i+1); 25 dfs(x+1,i); 26 if(fl) return; 27 reverse(a+1,a+i+1); 28 } 29 } 30 int main() 31 { 32 int i; 33 scanf("%d",&T); 34 while(T--) 35 { 36 fl=0; 37 scanf("%d",&n); 38 for(i=1;i<=n;++i) 39 scanf("%d",&a[i]); 40 for(maxd=0;maxd<=40;++maxd) 41 { 42 dfs(0,0); 43 if(fl) break; 44 } 45 printf("%d ",maxd); 46 } 47 return 0; 48 }