[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 }
相關文章
相關標籤/搜索