hdu 4911 Inversion

Inversion

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 2222    Accepted Submission(s): 859


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.
 

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).
 

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
 

Author
Xiaoxu Guo (ftiasch)
 

Source
 

Recommend
We have carefully selected several similar problems for you:   5257  5256  5255  5254  5253 


题意:输入n,k n为序列的长度,k为交换的次数,每次只能是相邻元素之间的交换,求该序列经过k次交换得到最小的逆序数。

若1个序列的逆序数大于0,总存在0<=i<n使得 swap(ai,ai+1)之后 逆序数减1;

因此用归并排序求出序列的逆序数cnt与k进行比较即可得到答案

还要注意 用int存储逆序数会数据溢出

AC代码:

 
     
     
  1. #include <stdio.h>
  2. #include "string.h"
  3. #include "math.h"
  4. long long int cnt;
  5. void Merge(int ss[],int ex,int ey,int sx,int sy)
  6. {
  7. int temp[100002],i=ex,j=sx,pos=ex;
  8. for(;i<=ey&&j<=sy;)
  9. {
  10. if(ss[i]<=ss[j])
  11. temp[pos++]=ss[i++];
  12. else
  13. {
  14. temp[pos++]=ss[j++];
  15. cnt+=(ey-i+1);
  16. }
  17. }
  18. while(i!=ey+1)
  19. temp[pos++]=ss[i++];
  20. while(j!=sy+1)
  21. temp[pos++]=ss[j++];
  22. for(i=ex;i<=sy;i++)
  23. {
  24. ss[i]=temp[i];
  25. }
  26. }
  27.  
  28. void Mergesort(int ss[],int left,int right)
  29. {
  30. int middle;
  31. if(left<right)
  32. {
  33. middle=(left+right)/2;
  34. Mergesort(ss,left,middle);
  35. Mergesort(ss, middle+1, right);
  36. Merge(ss,left,middle,middle+1,right);
  37. }
  38. }
  39. int main()
  40. {
  41. int n,k;
  42. while(scanf("%d%d",&n,&k)!=EOF)
  43. {
  44. int ss[100002];
  45. cnt=0;
  46. for(int i=0;i<n;i++)
  47. scanf("%d",&ss[i]);
  48. Mergesort(ss, 0, n-1);
  49. if(k>cnt) printf("0\n");
  50. else printf("%lld\n",cnt-k);
  51. }
  52. }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值