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; }
相关文章推荐
- tomcat下jndi的三种配置方式
- Java核心基础知识
- Apache 错误代码配置
- 第26讲 项目2--成绩等级
- PostgreSQL学习手册(常用数据类型)
- android通过okhttp访问自签名https网站(单向)
- nyoj742子串和再续【dp】
- [kuangbin带你飞]专题一 简单搜索 C - Catch That Cow poj 3278
- android 很多牛群叉界面库github地址
- ContentProvider两个应用之间访问数据
- JS中的this
- PostgreSQL学习手册(表的继承和分区)
- 【构】从配置替换谈适配器模式
- 对象序列化单例
- event.srcElement和e.target
- 奔小康赚大钱(km)
- Java基础学习27(异常处理二)
- 初探设计:Java继承何时用?怎么用?
- 606第九周周六赛 B - War
- Qt中丰富的容器类---数组QVector、链表QLinkedList、映射表QMap、哈希表QHash