题目描述
输入输出格式
输入格式:
共两行。第一行为铁盘个数N(1<=N<=50),第二行为N个不同的正整数,分别为从上到下的铁盘的半径R。(1<=R<=100)
输出格式:
一个正整数,表示使铁盘从小到大有序需要的最少翻转次数。
输入输出样例
输入样例#1:
5 2 4 3 5 1
输出样例#1:
5 迭代加深+A*剪枝把原序列离散后,目标序列是单调递增且相邻为1的序列每一次规定一个次数显然对于一个序列,至少要交换相邻不为1的数字个数如果加上这个次数大于规定次数就退出
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 struct Node 7 {int x,id; 8 }a[1001]; 9 int s[1001],ans,n; 10 bool cmp(Node a,Node b) 11 { 12 return a.x<b.x; 13 } 14 int count() 15 {int tot=0,i; 16 for (i=1;i<=n;i++) 17 if (abs(s[i+1]-s[i])!=1) tot++; 18 return tot; 19 } 20 void dfs(int k,int cnt) 21 {int i,j; 22 int l=count(); 23 if (l==0&&s[1]<s[2]) 24 {ans=k;return;} 25 if (ans||k+l>cnt||k==cnt) return; 26 for (i=2;i<=n;i++) 27 { 28 if (abs(s[i]-s[i+1])==1) continue; 29 for (j=1;j<=i/2;j++) 30 { 31 swap(s[j],s[i-j+1]); 32 } 33 dfs(k+1,cnt); 34 for (j=1;j<=i/2;j++) 35 { 36 swap(s[j],s[i-j+1]); 37 } 38 } 39 } 40 int main() 41 {int i,cnt; 42 cin>>n; 43 for (i=1;i<=n;i++) 44 { 45 scanf("%d",&a[i].x); 46 a[i].id=i; 47 } 48 sort(a+1,a+n+1,cmp); 49 for (i=1;i<=n;i++) 50 s[a[i].id]=i; 51 s[n+1]=n+1; 52 cnt=0; 53 while (!ans) 54 { 55 dfs(0,cnt); 56 cnt++; 57 } 58 cout<<ans; 59 }
时间: 2024-10-07 12:15:42