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): 556 Accepted Submission(s):
239
Problem Description
bobo has a sequence
a1,a2,…,an. 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 ai>aj.
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 ai>aj.
Input
The input consists of several tests. For each
tests:
The first line contains 2 integers n,k (1≤n≤105,0≤k≤109). The second line contains n integers a1,a2,…,an (0≤ai≤109).
The first line contains 2 integers n,k (1≤n≤105,0≤k≤109). The second line contains n integers a1,a2,…,an (0≤ai≤109).
Output
For each tests:
A single integer denotes the minimum number of inversions.
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次,使得逆对数最小,
思路,先求出整个序列的逆对数-k次就可,如果出现负数就输出为0.用归并排序求逆对数。
#include<iostream> #include<cstring> #include<cstdio> using namespace std; __int64 a[100005],cnt,c[100005]; __int64 k; void merg(int low, int mid, int high) { int i=low, j=mid+1; cnt=0; while(i<=mid&&j<=high) { if(a[i]>a[j]) { c[cnt++]=a[j++]; k+=mid-i+1; } else { c[cnt++]=a[i++]; } } while(i<=mid) { c[cnt++]=a[i++]; } while(j<=high) { c[cnt++]=a[j++]; } cnt=0;i=low; while(i<=high) { a[i++]=c[cnt++]; } } void merger(int low, int high) { int mid; if(low<high) { mid=(low+high)/2; merger(low,mid); merger(mid+1,high); merg(low,mid,high); } } int main() { int i,n,m; while(~scanf("%d%d",&n,&m)) { k=0; for(i=0; i<n; i++) { scanf("%I64d",&a[i]); } merger(0,n-1); if(k-m<=0) printf("0 "); else printf("%I64d ",k-m); } return 0; }