標籤:hdu 歸併
Problem Descriptionbobo 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.
InputThe 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).
OutputFor each tests:
A single integer denotes the minimum number of inversions.
Sample Input
3 12 2 13 02 2 1
Sample Output
12根據逆序數的定理如果逆序數大於0,那麼必定存在1<=i<n使得i和i+1交換後逆序數減1假設原逆序數為cnt,這樣的話,我們就可以得到答案是max(cnt-k,0)求逆序數可以用歸併的方法#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;int a[100005];int left[100005], right[100005];__int64 cnt;void merge(int* a, int p, int q, int r){ int i, j, k, n1, n2; n1 = q-p+1; n2 = r-q; for (i=0; i<n1; i++) { left[i] = a[p+i]; } for (i=0; i<n2; i++) { right[i] = a[q+i+1]; } left[n1] = right[n2] = 0x7fffffff; i = j = 0; for (k=p; k<=r; k++) { if (left[i] <= right[j]) { a[k] = left[i]; i++; } else { a[k] = right[j]; j++; cnt += n1-i; /**此步驟是在歸併排序法中加的一句,用來計數求逆序數的數目**/ } } return;}void mergesort(int* a, int p, int r){ int q; if (p < r) { q = (p+r)/2; mergesort(a, p, q); mergesort(a, q+1, r); merge(a, p, q, r); } return ;}int main(){ int n,k,i,j; while(~scanf("%d%d",&n,&k)) { cnt = 0; for(i = 0;i<n;i++) scanf("%d",&a[i]); mergesort(a,0,n-1); printf("%I64d\n",max(cnt-k,(__int64)0)); } return 0;}