• HDU 4911 Inversion


     HDU 4911      Inversion(归并排序)

    题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=86640#problem/A

    题目:

    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

    题意:

    有一个序列,可以交换相邻的两个数字不超过K次,求交换后逆序对数最少是多少。

    分析:

    1.求逆序对数,归并排序

    2.要先求原序列的逆序对数,如果每个逆序对都是相邻的,这交换后所求得的逆序对数最少sum-k,如果是负数,输出0

    代码:

     1 #include<cstdio>
     2 #include<iostream>
     3 using namespace std;
     4 const int maxn=100001;
     5 
     6 long long a[maxn],b[maxn];
     7 long long t,sum;
     8 
     9 void merge(int l,int m,int r)
    10 {
    11     int i=l,j=m+1,t=0;
    12     while(i<=m&&j<=r)
    13     {
    14         if(a[i]>a[j])
    15         {
    16             b[t++]=a[j++];
    17             sum+=m-i+1;
    18         }
    19         else
    20         {
    21             b[t++]=a[i++];
    22         }
    23     }
    24     while(i<=m)
    25     {
    26         b[t++]=a[i++];
    27     }
    28     while(j<=r)
    29     {
    30         b[t++]=a[j++];
    31     }
    32     for(int i=0;i<t;i++)
    33     {
    34         a[l+i]=b[i];
    35     }
    36 }
    37 
    38 void merge_sort(int l,int r)
    39 {
    40     if(l<r)
    41     {
    42         int m=(l+r)/2;
    43         merge_sort(l,m);
    44         merge_sort(m+1,r);
    45         merge(l,m,r);
    46     }
    47 }
    48 
    49 int main()
    50 {
    51     int n,k;
    52     while(scanf("%d%d",&n,&k)!=EOF)
    53     {
    54         sum=0;
    55         for(int i=0;i<n;i++)
    56         {
    57             scanf("%d",&a[i]);
    58         }
    59         merge_sort(0,n-1);
    60         if(sum-k<=0)
    61             printf("0
    ");
    62         else
    63             printf("%lld
    ",sum-k);
    64     }    
    65     return 0;
    66 }
    View Code

    开始没有看懂题意,仔细读题后发现这是一个求逆序对数的问题,和习题A是一样的

    我提交的时候是输出的lld 通过了,后来改成I64d也通过了。

  • 相关阅读:
    Java网络技术-待续
    Java输入输出技术
    Java数据库技术
    Java安全技术
    Java异常、事件、多线程
    网站产品设计
    C#-委派和事件
    Quartz 触发器(SimpleTrigger&CronTrigger )配置说明 & cronExpression表达式 转
    weblogic出现response already committed(转)
    Weblogic二种修改端口的方法(转)
  • 原文地址:https://www.cnblogs.com/ttmj865/p/4711844.html
Copyright © 2020-2023  润新知