假设初始状态为
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