假设初始状态为
a:2 3 1 5 4 6
则目标状态为
b:1 2 3 4 5 6且下标为初始状态中的3 1 2 4 5 6(a[3],a[1]...)
将置换群写成循环的形式
(2,3,1),(5,4),6就不用移动了。
移动方式2种
1:选循环内最小的数和其他len-1个数交换
2:选整个序列最小的数和循环内最小的数交换,转到1,再换回来。
#include<cstdio>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
int a[100005],b[100005];
int hash[100005];
bool vis[100005];
int main()
{
int n;
while(~scanf("%d",&n))
{
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++) scanf("%d",&a[i]),b[i]=a[i];
sort(b+1,b+1+n);
for(int i=1;i<=n;i++) hash[a[i]]=i;
int ans=0;
/*
2 3 1
1 2 3----id: 3 1 2
*/
for(int i=1;i<=n;i++)
{
if(vis[i]||a[i]==b[i]) continue;
int id=i,x=a[i],len=0,mins=0x3f3f3f3f,sum=0;
while(true)
{
sum+=x;
mins=min(mins,x);
vis[id]=true;
x=b[id];
id=hash[b[id]];
len++;
if(x==a[i]) break;
}
ans+=min(sum-mins+mins*(len-1),(sum-mins+b[1]*(len-1)+2*(b[1]+mins)));
}
printf("%d\n",ans);
}
return 0;
}
poj 3270 Cow Sorting 置换群 简单题,布布扣,bubuko.com
原文地址:http://blog.csdn.net/t1019256391/article/details/36176457