HDU 4911 Inversion

 HDU 4911      Inversion(归并排序)

题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=86640#problem/A

题目:

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次,求交换后逆序对数最少是多少。

分析:

1.求逆序对数,归并排序

2.要先求原序列的逆序对数,如果每个逆序对都是相邻的,这交换后所求得的逆序对数最少sum-k,如果是负数,输出0

代码:

 1 #include<cstdio>
 2 #include<iostream>
 3 using namespace std;
 4 const int maxn=100001;
 5 
 6 long long a[maxn],b[maxn];
 7 long long t,sum;
 8 
 9 void merge(int l,int m,int r)
10 {
11     int i=l,j=m+1,t=0;
12     while(i<=m&&j<=r)
13     {
14         if(a[i]>a[j])
15         {
16             b[t++]=a[j++];
17             sum+=m-i+1;
18         }
19         else
20         {
21             b[t++]=a[i++];
22         }
23     }
24     while(i<=m)
25     {
26         b[t++]=a[i++];
27     }
28     while(j<=r)
29     {
30         b[t++]=a[j++];
31     }
32     for(int i=0;i<t;i++)
33     {
34         a[l+i]=b[i];
35     }
36 }
37 
38 void merge_sort(int l,int r)
39 {
40     if(l<r)
41     {
42         int m=(l+r)/2;
43         merge_sort(l,m);
44         merge_sort(m+1,r);
45         merge(l,m,r);
46     }
47 }
48 
49 int main()
50 {
51     int n,k;
52     while(scanf("%d%d",&n,&k)!=EOF)
53     {
54         sum=0;
55         for(int i=0;i<n;i++)
56         {
57             scanf("%d",&a[i]);
58         }
59         merge_sort(0,n-1);
60         if(sum-k<=0)
61             printf("0
");
62         else
63             printf("%lld
",sum-k);
64     }    
65     return 0;
66 }
View Code

开始没有看懂题意,仔细读题后发现这是一个求逆序对数的问题,和习题A是一样的

我提交的时候是输出的lld 通过了,后来改成I64d也通过了。

原文地址:https://www.cnblogs.com/ttmj865/p/4711844.html