HDU 4911 Inversion - 疯狂的癫子 解题心得
原题:
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.
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≤ai≤10 9).
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≤ai≤10 9).
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
分析:
先用归并法求逆序数,再将逆序数减去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\n"); else printf("%I64d\n", k - m); } return 0; }