Inversion
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 4072 Accepted Submission(s): 1479
Problem 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≤a i≤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≤a i≤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
Sample Output
1 2
题意:
给你n个数,有k次交换左右相邻数的机会,让你求出最小可能的逆序数。
注解:
只要理解了每交换一次总逆序数减一就很好做了。因为你每交换一次,影响的只有相邻两个数之间的逆序数。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;
const int MANX=1e5+7;
int c[MANX],a[MANX];long long int sum;
void mege(int s,int e)
{
int m;
if(e>s)
{
m=s+(e-s)/2; //找中点
mege(s,m); //左边进行递归
mege(m+1,e); //右边进行递归
int i=s,j=m+1;
while(i<=m&&j<=e) //从左边的树里的首元素开始与右边树里的首元素进行比较
{
if(a[i]>a[j])
{j++;sum+=m-i+1;} //额,进行计算逆序数的,可以忽略
else
{
i++;
}
}
sort(a+s,a+e+1); //每层进行的排序
}
return ;
}
int main()
{
int n,k;
while(~scanf("%d%d",&n,&k))
{
sum=0;
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
mege(1,n);
//printf("%d\n",sum);
if(sum>k) //如果提供给你的最大交换次数大于总的逆序数,那么可以直接换成最优的排好序的状态,逆序数就直接为零
printf("%lld\n",sum-k);
else
printf("0\n");
}
return 0;
}