• HDU 1394 Minimum Inversion Number(树状数组)


     

    题目大意

     

    给一个 0~n-1 的排列(n≤5000),可以把这个排列的前 m(0≤m≤n-1) 个数移到排列的最后:如下面的例子所示

           a1, a2, ..., an-1, an

           a1, a2, ..., an-1, an

           a3, a4, ..., an, a1, a2

           ...

           an, a1, a2, ..., an-1

    现在问,在这 n 个排列中,逆序数最小的是多少,并输出这个最小逆序数

    逆序指的是: i<j && ai>aj

     

    做法分析

     

    先考虑怎么求逆序数:树状数组

    BIT[i] 记录的是 [i-i&(-i), i] 这个区间中,有多少个数,注意:树状数组的下标不能从 0 开始

    那么,每读入一个数 ai

            我们先更新一次: update(ai+1, 1)

            然后求比这个数大的数有多少个: query(n+1)-query(ai+1)

    求和之后便是原始序列中逆序对的个数了

    先求出原始序列的逆序数,设为 sum

     

    考虑:每次把序列中第一个数 a1 移到序列的末尾,我们应该怎么变换?没错:把整个序列扫描一遍:

            如果这个数比 a1 小,那么 sum-- (没有移动之前,他们是一个逆序对,移动之后,不是逆序对了)

            如果这个数比 a1 大,那么 sum++ (没有移动之前,他们不是逆序对,移动之后,他们构成了一个逆序对)

    这样扫描一遍之后,便得到了当前这个新序列的逆序对的个数,以此统计最小值即可

    时间复杂度:o(n2)

     

    参考代码

    HDU 1394
     1 #include <cstring>
     2 #include <cstdio>
     3 #include <iostream>
     4 
     5 using namespace std;
     6 
     7 const int N=5006;
     8 int n, BIT[N], a[N];
     9 
    10 void update(int pos, int val)
    11 {
    12     for(; pos<N; pos+=pos&(-pos)) BIT[pos]+=val;
    13 }
    14 
    15 int query(int pos)
    16 {
    17     int ans=0;
    18     for(; pos>0; pos-=pos&(-pos)) ans+=BIT[pos];
    19     return ans;
    20 }
    21 
    22 int main()
    23 {
    24     int n;
    25     while(scanf("%d", &n)!=EOF)
    26     {
    27         memset(BIT, 0, sizeof BIT);
    28         int sum=0;
    29         for(int i=0; i<n; i++)
    30         {
    31             scanf("%d", &a[i]);
    32             update(a[i]+1, 1);
    33             sum+=query(n+1)-query(a[i]+1);
    34         }
    35         int ans=sum;
    36         for(int i=0; i<n; i++)
    37         {
    38             for(int j=0; j<n; j++)
    39             {
    40                 if(a[i]>a[j]) sum--;
    41                 if(a[i]<a[j]) sum++;
    42             }
    43             if(sum<ans) ans=sum;
    44         }
    45         printf("%d\n", ans);
    46     }
    47     return 0;
    48 }

    题目链接 & AC通道

    HDU 1394 Minimum Inversion Number

  • 相关阅读:
    DNS正向反向解析
    varnish-4.0.5的反向代理 缓存测试 负载均衡实验
    DS8700 硬盘更换略
    ftp虚拟用户
    maven mvn 命令行 编译打包
    linux下的springboot项目启动文件
    linux系统安装gcc
    linux系统下安装两个或多个tomcat
    linux系统的磁盘挂载
    常用linux命令
  • 原文地址:https://www.cnblogs.com/zhj5chengfeng/p/3040816.html
Copyright © 2020-2023  润新知