您的位置:首页 > 其它

poj 3270 Cow Sort(置换群的分解)

2016-12-02 23:30 351 查看

Problem Link

poj Cow Sort

题目大意:给你一串数字,a1,a2,...,an互不相同,让你把他变换到从小到大的顺序排列其中交换两个数的代价是ai+aj,问你最小代价。

刚开始的时候不知道置换群这种东西,用贪心做了好久,最终还是wa了。。。

Analysis

就是一个简单的置换群的分解了,将置换分解成循环,一种方式是在和循环里面把最小的座位媒介去和其他的交换,这样会的到一个最小值;但是还有我们知道一个置换可以分解成几个对换的乘积,所以说我们可以用序列里面的最小元去与一个循环中的最小元换然后在做置换,最后比较这两种方式,取最小值。

#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<cmath>
#define Debug(x) cout<<(x)<<endl
#define fi first
#define se second
using namespace std;
typedef long long LL;
typedef pair<int,int > PII;
typedef map<int,int >::iterator MIT;

const int maxn = 1e4+10;

int a[maxn];
int p[maxn];
int nowp[maxn*10];

int main() {

int n;
while(scanf("%d",&n)!=EOF)
{
for(int i=0 ; i<n ; ++i)scanf("%d",&a[i]);
memcpy(p,a,sizeof(a));
memset(nowp,0,sizeof(nowp));
for(int i=0 ; i<n ; ++i)
nowp[a[i]] = i;
sort(p,p+n);
LL ans =0;
for(int i=0 ; i<n ; ++i)
{
LL ans1 = 0;
LL ans2 = p[i]+p[0];
while(nowp[p[i]]!=i)
{
int np = nowp[p[i]];
ans2 +=(p[np]+p[0]);
ans1+=(p[i]+p[np]);
//ans+=(p[i]+p[np]);
swap(nowp[p[np]],nowp[p[i]]);
}
ans2+=(p[i]+p[0]);
ans+=min(ans2,ans1);
}

cout<<ans<<endl;
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息