BZOJ1697 [Usaco2007 Feb] Cow Sorting牛排序


JOHN farmer preparing his N (1 <= N <= 10,000) cows queued for action. Because cattle have a big temper might make trouble, JOHN trying to sort cattle by size of temper. Each cow in a temper are integers between 1 and 100,000, and the value is not the same temper two cows. In the sorting process, JOHN can be exchanged in any position in two cows. Because of the large movement of bad temper cattle, JOHN X + Y seconds required to exchange the X and Y values ​​temper two cows. Please help JOHN calculate all the good steak order the shortest time.

Input
Line 1: a number, N.
Of 2 ~ N + 1 rows: each row a number of row i + 1 is the value of the i temper cow.

Output
Line 1: a number, all the good steak order the shortest time.
The Input the Sample
. 3
2
. 3
1
input interpretation:
queue has three cows, they were temper 2,3, 1.
Sample Output

7
Output Interpreter:
231: initial sequence
213: exchange temper cattle 3 and 1 (time = 1 + 3 = 4).
123: exchange temper cattle 1 and 2 (time = 2 + 1 = 3).
explanations
permutation group 2333
solution to a problem from the novosbirsk
1. identify the initial and target states. Obviously, the target state is the state after ordering.
2. Draw permutation group, looking circulation inside. For example, the number is 845327
significantly, the target state is 234,578, can be written as two cycles:
(827) (435).
3. One cycle of observation, obviously, make the least costly exchange, you should use the smallest number inside the loop 2, to, 7 and 8 exchange with the other two numbers. The cost of this exchange is:
SUM - min + (len -. 1) * min
after simplified as:
SUM + (len - 2) * min
where, sum for the circulation of all numbers and, len is the length, min for the ring the lowest number inside.

4. Considering another case, we can call a number from the other inside the loop, the loop enters into the exchange less costly. For example an initial state:
18976
decomposed into two cycles:
(1) (8697), obviously, for the second cycle (8697), the minimum number is 6. We can deploy the entire series the smallest number 1 into this cycle. The second cycle becomes: (8197). Let this one task after another and exchange 6, so after six cycles back. Cost of doing so is obviously:
SUM + min + (len +. 1) * Smallest
wherein, sum for the circulation of all numbers and, len is the length, min for the lowest number ring which, smallest whole number of columns in a minimum number.

5. Thus, a sort cycle, which is the cost sum - min + (len - 1) * min and sum + min + (len + 1) * the smallest of the small number.

6. We compute cycle time, do not need to record all of the elements of this cycle, this cycle only need to record the minimum number and and.

7. When the stored number, we can use a hash structure, the position of the element and its association, known elements in order to achieve the purpose of the element can be quickly reverse lookup location. This unnecessary one by one to search.

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define ll long long
#define inf 1000000000
using namespace std;
inline ll read()
{
    ll x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int n, gmn, cnt, years;
int v[10005],id[10005],disc[10005];
int mn[10005],sum[10005],len[10005];
bool Show [10005];
int find(int x)
{
	int l=1,r=n;
	while(l<=r)
	{
		int mid=(l+r)>>1;
		if(disc[mid]>x)r=mid-1;
		else if(disc[mid]==x)return mid;
		else l=mid+1;
	}
}
void solve(int x)
{
	to [x] = 1; cnt ++;
	len[cnt]=1;sum[cnt]+=v[x];mn[cnt]=min(mn[cnt],v[x]);
	int now=x;
	while(v[id[now]]!=v[x])
	{
		now=id[now];vis[now]=1;
		len[cnt]++;sum[cnt]+=v[now];mn[cnt]=min(mn[cnt],v[now]);
	}
}
int main ()
{
	memset(mn,127/3,sizeof(mn));gmn=inf;
	n=read();
	for(int i=1;i<=n;i++)
		v[i]=read(),disc[i]=v[i],gmn=min(gmn,v[i]);
	sort(disc+1,disc+n+1);
	for(int i=1;i<=n;i++)
		id[i]=find(v[i]);
	for(int i=1;i<=n;i++)
		if(!vis[i]&&i!=id[i])solve(i);
	for(int i=1;i<=cnt;i++)
	{
		int t1 = (len [in] -2) * Mn [I];
		int t2=mn[i]+(len[i]+1)*gmn;
		ans+=sum[i]+min(t1,t2);
	}
	printf("%d",ans);
	return 0;
}

  

Guess you like

Origin www.cnblogs.com/cutemush/p/12133962.html