Inversion
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 3171 Accepted Submission(s): 1154
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.
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).
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次相邻数调换后,有多少逆序数对;
解题思路:用归并排序求出原序列的逆序数对cnt,再求max(cnt - k, 0 ),即为答案;
#include"iostream" #include"cstdio" #include"cstring" using namespace std; int a[100005]; int b[100005]; //辅助数组 long long cnt; void Merge(int a[],int p,int q,int r, int b[]){ int s = p, t = q + 1, k = p; while(s <= q && t <= r){ if(a[s] <= a[t]){ b[k ++] = a[s ++]; }else{ b[k ++] = a[t ++]; cnt += (q - s + 1); // 在原序列a[s...q] > a[t],故有逆序数对 (q-s+1) 个 } } if(s == q + 1) for(;t <= r;t ++) b[k ++] = a[t]; else for(;s <= q;s ++) b[k ++] = a[s]; for(int i = p;i < k;i ++) a[i] = b[i]; } void BottomUpSort(int a[],int first,int last,int b[]){ if(first < last){ int mid = (first + last) / 2; BottomUpSort(a, first, mid, b); BottomUpSort(a, mid + 1, last, b); Merge(a, first, mid, last, b); } } int main(){ int n, k; while(scanf("%d%d",&n,&k) != EOF){ cnt = 0; for(int i = 1;i <= n;i ++) scanf("%d",&a[i]); BottomUpSort(a,1,n, b); cnt = (cnt - k) > 0 ? (cnt - k) : 0; //for(int i = 1;i <= n;i ++) printf("%d ",a[i]); printf("\n"); printf("%I64d\n",cnt); } return 0; }