您的位置:首页 > 其它

bzoj2824 铁盘整理【迭代加深搜索】

2018-01-04 21:50 344 查看

解题思路:

先把数组离散化。

可以看出最多2n-2步可以排完(i从n到2,每次把第i大的数转到第一位,再转到第i位)。

考虑迭代加深搜索,那如何制定估价函数呢?

注意到翻转a[1]~a[i],只会改变a[i]与a[i+1]的差,而排好序的数列abs(a[i+1]-a[i])<=1,所以只要abs(a[i+1]-a[i])>1,就至少要翻转一次,这样估价函数就出来了。

#include<bits/stdc++.h>
using namespace std;

int getint()
{
int i=0,f=1;char c;
for(c=getchar();(c!='-')&&(c<'0'||c>'9');c=getcha
4000
r());
if(c=='-')c=getchar(),f=-1;
for(;c>='0'&&c<='9';c=getchar())i=(i<<3)+(i<<1)+c-'0';
return i*f;
}

const int N=55;
int n,m,dep,a
,b
;

void lsh()
{
sort(b+1,b+n+1);
m=unique(b+1,b+n+1)-b-1;
for(int i=1;i<=n;i++)a[i]=lower_bound(b+1,b+m+1,a[i])-b;
}

bool dfs(int step,int last)
{
if(step==dep)
{
for(int i=1;i<=n;i++)
if(a[i]!=i)return false;
return true;
}
int tmp=0;
for(int i=1;i<=n;i++)if(abs(a[i+1]-a[i])>1)tmp++;
if(step+tmp>dep)return false;
for(int i=2;i<=n;i++)
{
if(i==last)continue;
reverse(a+1,a+i+1);//ans[step+1]=i;
if(dfs(step+1,i))return true;
reverse(a+1,a+i+1);
}
return false;
}

int main()
{
//freopen("lx.in","r",stdin);
n=getint();
for(int i=1;i<=n;i++)b[i]=a[i]=getint();
lsh();
a[n+1]=m+1;
dep=0;
for(int i=1;i<=n;i++)if(abs(a[i+1]-a[i])>1)dep++;
while(!dfs(0,0))dep++;
printf("%d\n",dep);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: