[POJ 3270]Cow Sorting

Description

Farmer John's N (1 ≤ N ≤ 10,000) cows are lined up to be milked in the evening. Each cow has a unique "grumpiness" level in the range 1...100,000. Since grumpy cows are more likely to damage FJ's milking equipment, FJ would like to reorder the cows in line so they are lined up in increasing order of grumpiness. During this process, the places of any two cows (not necessarily adjacent) can be interchanged. Since grumpy cows are harder to move, it takes FJ a total of X+Y units of time to exchange two cows whose grumpiness levels are X and Y.node

Please help FJ calculate the minimal time required to reorder the cows.ios

Input

Line 1: A single integer:  N
Lines 2.. N+1: Each line contains a single integer: line  i+1 describes the grumpiness of cow  i

Output

Line 1: A single line with the minimal time required to reorder the cows in increasing order of grumpiness.

Sample Input

3 ui

2this

3spa

1code

Sample Output

7blog

Hint

2 3 1 : Initial order. 
2 1 3 : After interchanging cows with grumpiness 3 and 1 (time=1+3=4). 
1 2 3 : After interchanging cows with grumpiness 1 and 2 (time=2+1=3).

题目大意:

给你一个排列,而后让你交换到递增排列,交换X和Y的位置,花费就是X+Y,求变成递增序列的最小花费排序

题解:

咱们先说说样例:2 3 1 —— ①ip

编号分别为:       1 2 3 —— ②get

排序后的编号为:3 1 2 —— ③

这样一来咱们就能够理解为②通过一系列变换就造成了③(也就是最终形态),那么既然是序列变换,咱们考虑置换。那么②和③造成了一个置换。

$$\binom{1,2,3}{3,1,2}$$

那么对于一个置换,咱们分别处理置换上的每个环,有两点能够确定:

  1.一个环能够经过自身内部的交换造成最终形态。

  2.当每个环都造成了最终形态时,序列也就从②变到了三③。

那么接下来怎么求出代价的最小值呢?


 

 

首先咱们分别考虑每个环,若是不考虑其余环对这个环的影响(也就是说,这个环在本身内部交换)。

此时有一个贪心十分显然,用一个环的最小值去和环上的每个数分别交换所付出的代价最小。

下面咱们给出证实:

  假设咱们当前处理的环长度为$k$,那么咱们一定要交换$k-1$次。(不可能更多,由于环已经肯定了每个数的前后关系,咱们只要两两之间分别交换就好)

  ∴咱们要在环上肯定一个起点$x$,这个$x$沿着环交换一圈便可。

  ∴付出的代价为$sum-v[x]+v[x]*(tot-1)$(sum为环上权值和,tot为环上的点数,v[x]为起点的权值)

  ∴权值越小越好。

  综上所述,得证。

接下来咱们考虑其余环的影响。


 

假设某一个环上的最小值比当前处理的环的最小值还要小,那么咱们只要将这两个环的最小值先交换,而后处理完当前环,在交换回去。

那么这样作的代价和单独考虑一个环的代价取个最小值,就是处理完这个环的代价。

因而乎咱们只要求出全部数中的最小值min,再将它代入每个环求一遍,而后和这个环自身处理的代价比较一下就好。

 1 //Never forget why you start
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<cstdlib>
 5 #include<cstring>
 6 #include<cmath>
 7 #include<algorithm>
 8 #define inf (2147483647)
 9 using namespace std;
10 int n,m,ans;
11 struct node{
12   int x,id,pos;
13   friend bool operator < (const node a,const node b){
14     return a.x<b.x;
15   }
16 }a[10005];
17 bool cmp(const node a,const node b){
18   return a.id<b.id;
19 }
20 struct part{
21   int mmin,sum,tot;
22   part(){}
23   part(int _mmin,int _sum,int _tot){
24     mmin=_mmin;
25     sum=_sum;
26     tot=_tot;
27   }
28 }o[10005];
29 int vis[10005],cnt,mmin[10005],sum[10005],tot[10005],tmp,p,lm;
30 void dfs(int r){
31   vis[r]=1;
32   p+=a[r].x;
33   cnt++;
34   tmp=min(tmp,a[r].x);
35   if(vis[a[r].pos]==1){mmin[r]=tmp;sum[r]=cnt;tot[r]=p;return;}
36   else dfs(a[r].pos);
37   tot[r]=p;
38   mmin[r]=tmp;
39   sum[r]=cnt;
40 }
41 int main(){
42   int i,j;
43   while(scanf("%d",&n)!=EOF){
44     memset(mmin,0,sizeof(mmin));
45     memset(vis,0,sizeof(vis));
46     memset(a,0,sizeof(a));
47     memset(o,0,sizeof(o));
48     memset(sum,0,sizeof(sum));
49     memset(tot,0,sizeof(tot));
50     lm=0;ans=0;
51     for(i=1;i<=n;i++){
52       scanf("%d",&a[i].x);
53       a[i].id=i;
54     }
55     sort(a+1,a+n+1);
56     for(i=1;i<=n;i++)a[i].pos=i;
57     sort(a+1,a+n+1,cmp);
58     for(i=1;i<=n;i++)
59       if(!vis[i]){
60     cnt=0;
61     p=0;
62     tmp=inf;
63     dfs(i);
64     o[++lm]=part(mmin[i],sum[i],tot[i]);
65       }
66     tmp=inf;
67     for(i=1;i<=lm;i++)tmp=min(tmp,o[i].mmin);
68     for(i=1;i<=lm;i++){
69       ans+=min(2*(tmp+o[i].mmin)+(o[i].sum-1)*tmp+o[i].tot-o[i].mmin,o[i].tot-o[i].mmin+(o[i].sum-1)*o[i].mmin);
70     }
71     printf("%d\n",ans);
72   }
73   return 0;
74 }
相关文章
相关标签/搜索