[HDOJ4911]Inversion

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4911

 

 

Inversion

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 2744    Accepted Submission(s): 1015


Problem Description
bobo has a sequence a 1,a 2,…,a n. He is allowed to swap two adjacent numbers for no more than k times.

Find the minimum number of inversions after his swaps.

Note: The number of inversions is the number of pair (i,j) where 1≤i<j≤n and a i>a j.
 

 

Input
The input consists of several tests. For each tests:

The first line contains 2 integers n,k (1≤n≤10 5,0≤k≤10 9). The second line contains n integers a 1,a 2,…,a n (0≤a i≤10 9).
 

 

Output
For each tests:

A single integer denotes the minimum number of inversions.
 

 

Sample Input
3 1 2 2 1 3 0 2 2 1
 

 

Sample Output
1 2

  求交换k次以后所获得的数列的最小的逆序数。

  如果逆序数大于0,说明数列中有两个数可以交换,使得逆序数-1。所以所求交换k次所得数列最小逆序数的结果就是排序结束后交换次数-k,这个结果大于等于0。

 

代码如下:

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 
 5 using namespace std;
 6 
 7 typedef long long LL;
 8 const int maxn = 100010;
 9 int num[maxn];
10 int Right[maxn], Left[maxn];
11 LL ans;
12 
13 void merge(int* num, int p, int q, int r) {
14     int n1, n2, i, j, k;
15     n1 = q - p + 1;
16     n2 = r - q;
17     for(i = 0; i < n1; i++) {
18         Left[i] = num[p+i];
19     }
20     for(i = 0; i < n2; i++) {
21         Right[i] = num[q+i+1];
22     }
23     Left[n1] = Right[n2] = 0x7FFFFFFF;
24     i = 0;
25     j = 0;
26     for(k = p; k <= r; k++) {
27         if(Left[i] <= Right[j]) {
28             num[k] = Left[i];
29             i++;
30         }
31         else {
32             num[k] = Right[j];
33             j++;
34             ans += (n1 - i);
35         }
36     }
37 }
38 
39 void mergesort(int* num, int p, int r) {
40     int q;
41     if(p < r) {
42         q = (p + r) / 2;
43         mergesort(num, p, q);
44         mergesort(num, q+1, r);
45         merge(num, p, q, r);
46     }
47 }
48 
49 int main() {
50     int n, k;
51     while(~scanf("%d %d", &n, &k)) {
52         ans = 0;
53         for(int i = 0; i < n; i++) {
54             scanf("%d", &num[i]);
55         }
56         mergesort(num, 0, n-1);
57         cout << ((ans-k) > LL(0) ? ans-k : 0) << endl;
58     }
59 }

 

转载于:https://www.cnblogs.com/kirai/p/4746257.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值