1010 Swaps and Inversions(2018 Multi-University Training Contest 2)

Swaps and Inversions

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3588    Accepted Submission(s): 976


Problem Description
Long long ago, there was an integer sequence a.
Tonyfang think this sequence is messy, so he will count the number of inversions in this sequence. Because he is angry, you will have to pay x yuan for every inversion in the sequence.
You don't want to pay too much, so you can try to play some tricks before he sees this sequence. You can pay y yuan to swap any two adjacent elements.
What is the minimum amount of money you need to spend?
The definition of inversion in this problem is pair  (i,j) which 1i<jn and ai>aj.
 
Input
There are multiple test cases, please read till the end of input file.
For each test, in the first line, three integers, n,x,y, n represents the length of the sequence.
In the second line, n integers separated by spaces, representing the orginal sequence a.
1n,x,y100000, numbers in the sequence are in [109,109]. There're 10 test cases.
 
Output
For every test case, a single integer representing minimum money to pay.
 
Sample Input
3 233 666
1 2 3
3 1 666
3 2 1
 
Sample Output
0
3

题意:给定一个数组,如果存在逆序对需要花费 逆序对数乘以x,可以通过交换位置来改变逆序对的个数,但是每次交换需要花费y,求最小代价。
分析:每次交换最多能减少一对逆序对,所以只用 计算逆序对对数,判断逆序对和交换的代价,选小者。
 
 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 long long n,x,y;
 6 int t;
 7 int num[100000];
 8 long long cnt;
 9 void merge(int *a , int first, int mid, int last)
10 {
11     int * temp = new int[last - first + 1];     
12     int first1 = first, last1 = mid;
13     int first2 = mid + 1, last2 = last;
14     int index = 0;
15     while(first1 <= last1 && first2 <= last2)
16     {
17         if(a[first1 ] <= a[first2])
18         {
19             temp[index++] = a[first1++];
20         }
21         else
22         {
23             cnt += last1 - first1 + 1;
24             temp[index++] = a[first2++];
25         }
26     }
27     while(first1 <= last1)
28     {
29         temp[index++] = a[first1++];
30     }
31     while(first2 <= last2)
32     {
33         temp[index++] = a[first2++];
34     }
35     int i;
36     for(i = first; i <= last; i++)
37     {
38         a[i] = temp[i - first];
39     }
40     delete [] temp;
41     return;
42 }
43 void inv_pair(int *a, int first, int last)
44 {
45     if(last - first > 0)
46     {
47         int mid = (last + first) / 2;
48         inv_pair(a, first, mid);
49         inv_pair(a, mid + 1, last);
50         merge(a, first, mid, last);
51     }
52     return;
53 }
54 
55 
56 
57 int main()
58 {
59         while(scanf("%d%d%d",&n,&x,&y)!=EOF) {
60         cnt = 0;
61         for(int i=0; i<n; ++i) {
62             scanf("%d",&num[i]);
63         }
64         
65         inv_pair(num,0,n-1);
66         //cout<<cnt<<endl;
67         if(x>y) {
68             printf("%lld\n",cnt*y);
69         } else {
70             printf("%lld\n",cnt*x);
71         }
72     }
73     
74     return 0;
75 }

求逆序对方法来自其他博客,但是找不到该博主的链接,respect(侵删)

猜你喜欢

转载自www.cnblogs.com/nothing-fun/p/9387864.html