您的位置:首页 > 其它

[AHOI2012]铁盘整理

2017-09-23 19:33 204 查看

题目描述





输入输出格式

输入格式:

共两行。第一行为铁盘个数N(1<=N<=50),第二行为N个不同的正整数,分别为从上到下的铁盘的半径R。(1<=R<=100)

输出格式:

一个正整数,表示使铁盘从小到大有序需要的最少翻转次数。

输入输出样例

输入样例#1:

5
2 4 3 5 1


输出样例#1:

5

[b]迭代加深+A*剪枝
把原序列离散后,目标序列是单调递增且相邻为1的序列
每一次规定一个次数
显然对于一个序列,至少要交换相邻不为1的数字个数
如果加上这个次数大于规定次数就退出[/b]


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct Node
{int x,id;
}a[1001];
int s[1001],ans,n;
bool cmp(Node a,Node b)
{
return a.x<b.x;
}
int count()
{int tot=0,i;
for (i=1;i<=n;i++)
if (abs(s[i+1]-s[i])!=1) tot++;
return tot;
}
void dfs(int k,int cnt)
{int i,j;
int l=count();
if (l==0&&s[1]<s[2])
{ans=k;return;}
if (ans||k+l>cnt||k==cnt) return;
for (i=2;i<=n;i++)
{
if (abs(s[i]-s[i+1])==1) continue;
for (j=1;j<=i/2;j++)
{
swap(s[j],s[i-j+1]);
}
dfs(k+1,cnt);
for (j=1;j<=i/2;j++)
{
swap(s[j],s[i-j+1]);
}
}
}
int main()
{int i,cnt;
cin>>n;
for (i=1;i<=n;i++)
{
scanf("%d",&a[i].x);
a[i].id=i;
}
sort(a+1,a+n+1,cmp);
for (i=1;i<=n;i++)
s[a[i].id]=i;
s[n+1]=n+1;
cnt=0;
while (!ans)
{
dfs(0,cnt);
cnt++;
}
cout<<ans;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: