您的位置:首页 > 其它

HDU 4911 归并排序题目解析

2015-11-12 21:14 417 查看

上题目

Inversion Time Limit: 2000/1000 MS (Java/Others) Memory Limit:

131072/131072 K (Java/Others) Total Submission(s): 2924 Accepted

Submission(s): 1081

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

翻译

鉴于本人弱菜的英语 翻译一下题意

第一行给2个数 N K n表示下面一行数的个数 看表示你能操作的步数

问在进行最多K步操作之后最少能有几对逆序对

分析

首先说求逆序对

常见2种方法: 归并 和 树状数组 。 这里先讲归并 (树状数组不会啊)

然后分析最小问题

如何营造最小的情况?

每一步都不浪费 每一步减少一个逆序对

可以这么想如果两个数是逆序的 那么夹杂在两者中间的数也一定是逆序的 这和数列是否排好序无关

所以直接用归并排序计算出逆序对的个数减去K即可

但是注意不会出现负值

下面贴代码

归并排序的代码挺重要的 尽量多敲几遍 多理解

下面代码中的递归归并排序函数可以当作模板用

#include<stdio.h>
#include<string.h>
long long count = 0;
int a[100000 + 5];
int b[100000 + 5];
void Merge(int sourceArr[], int tempArr[], int startIndex, int midIndex, int endIndex)
{
int i = startIndex, j = midIndex + 1, k = startIndex;
while (i != midIndex + 1 && j != endIndex + 1)
{
if (sourceArr[i] >= sourceArr[j])
tempArr[k++] = sourceArr[i++];
else
{
tempArr[k++] = sourceArr[j++];
count += midIndex - i + 1;
}
}
while (i != midIndex + 1)
tempArr[k++] = sourceArr[i++];
while (j != endIndex + 1)
tempArr[k++] = sourceArr[j++];
for (i = startIndex; i <= endIndex; i++)
sourceArr[i] = tempArr[i];
}

void MergeSort(int sourceArr[], int tempArr[], int startIndex, int endIndex)
{
int midIndex;
if (startIndex < endIndex)
{
midIndex = (startIndex + endIndex) / 2;
MergeSort(sourceArr, tempArr, startIndex, midIndex);
MergeSort(sourceArr, tempArr, midIndex + 1, endIndex);
Merge(sourceArr, tempArr, startIndex, midIndex, endIndex);
}
}

int main(void)
{
int t, i, k, min, n, k;
while (scanf_s("%d %d", &n, &k) != EOF)
{
count = 0;
memset(a, 0, sizeof(a));
for (i = 1; i <= n; i++)
scanf_s("%d", &a[i]);
MergeSort(a, b, 0, n - 1);
if(count >= k)
count -=k;
else
count = 0;
printf("%d\n", count);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: