Description:
It gives you a sequence of numbers (each digit is unique). Each time you exchange any two numbers, the cost is the sum of the two numbers, ask the minimum cost to sort the sequence in ascending order.
The specific method of the question is to refer to Liu rujia's "algorithm art and informatics ocai". The general idea is: To solve it in another way in the future,
1. Find the initial and target statuses. Obviously, the target status is the sorted status.
2. Draw a replacement group and find a loop in it. For example, the number is 8 4 5 3 2 7
Obviously, The target status is 2 3 4 5 7 8, which can be written into two cycles: (8 2 7) (4 3 5 ).
3. observe one of the loops. Obviously, to minimize the exchange cost, use the smallest number 2 in the loop to exchange with the other two numbers 7 and 8. The price of this exchange is:
Sum-min + (LEN-1) * min
Simplified:
Sum + (LEN-2) * min
Sum is the sum of all numbers in the loop, Len is the length, and Min is the smallest number in the ring.
4. Considering another situation, we can call a number from another loop to enter this loop, reducing the exchange cost. For example, initial status: 1 8 9 76
Can be divided into two cycles: (1) (8 6 9 7), obvious, the second cycle is (8 6 97), the minimum number is 6. We can draw the smallest number 1 in the entire series to enter this loop. Change the second cycle to (8 1 97 ). Let this 1 complete the task, and then exchange with 6, let 6 return to the loop again. The cost of doing so is obvious:
Sum + min + (LEN + 1) * smallest
Sum is the sum of all the numbers in the cycle, Len is the length, Min is the smallest number in the ring, and smallest is the smallest number in the entire series.
5. therefore, the cost of sorting a loop is sum-min + (LEN-1) * min and sum + min + (LEN + 1) * small number of smallest. However, we do not know how to introduce the two formulas here.
6. When calculating a loop, we do not need to record all the elements of the loop. We only need to record the minimum number and sum of the loop.
7. When storing data, we can use a hash structure to map the elements and their locations to know the elements and quickly reverse query the element location. In this way, you do not need to search one by one.
#include <cstdio>#include <iostream>#include <cstring>#include <algorithm>#include <cmath>using namespace std;int seq[11111];int to[11111];int indexn[1111100];bool vis[1111100];int main(){int n;while(scanf("%d",&n)!=EOF){ memset(vis,0,sizeof(vis)); for(int i=1;i<=n;i++) { scanf("%d",&seq[i]); indexn[seq[i]]=i; to[i]=seq[i]; } sort(to+1,to+1+n); int res=0; for(int i=1;i<=n;i++) { if(!vis[i]) { int start=seq[i]; int minn=9999999;int len=0;int sum=0;int now=i; do { vis[now]=true; sum+=seq[now]; len++; minn=min(minn,seq[now]); if(to[now]==start) break; now=indexn[to[now]]; }while(true); int sum1=sum-minn+(len-1)*minn; int sum2=sum+minn+(len+1)*to[1]; res+=min(sum1,sum2); } } cout<<res<<endl;}return 0;}