zoukankan      html  css  js  c++  java
  • hdu 1394 Minimum Inversion Number

    题目链接:hdu 1394 Minimum Inversion Number

    该题是求最小逆序对的扩展。可以使用树状数组来实现。对于$n$个数的序列$A$,其第$i$个数($iin [0,n)$)的逆序数$r_i$可以表示为它的角标$i$减去在它之前且不大于它的数的个数。例如对序列A = {1,3,5,9,0,8,5,7,4,2}中的数,A[8] = 4。其逆序数$r_8 = 8 - 3 = 5$,第二个3表示三个在它前面且比它小的数:{1,3,0}。从而我们可以得到第$i$个数的逆序数公式:

    egin{equation} r_i = i - sum_{0 leq j < i And A_j leq A_i } 1 end{equation}

    对于整个序列$A$有

    egin{equation} R = sum_{0 leq i < n}r_i end{equation}

    可以使用树状数组的前i项的和sum(i)函数来快速的计算$sum_{0 leq j < i And A_j leq A_i } 1$,并且使用add(i+1)来对该数进行计数。

    得到初始数列的逆序数后,可以轻松地计算变换后序列的逆序数。

    如果删除掉第一个数$A_1$,那么逆序数会减小$A_1$。

    在把第一个数放到数列结尾,那么逆序数又会增加$n-A_1-1$

    从而可以尝试所有的变换方法,最终取最小值即可。

    代码如下:

     1 #include <cstdlib>
     2 #include <cstdio>
     3 #include <iostream>
     4 #include <cstring>
     5 #define MAXN  5005
     6 using namespace std;
     7 int bit[MAXN];
     8 int arr[MAXN];
     9 int n;
    10 int lowbit(int x)
    11 {
    12     return x&(-x);
    13 }
    14 int sum(int x)
    15 {
    16     int ans = 0;
    17     while( x > 0 )
    18     {
    19         ans += bit[x];
    20         x -= lowbit(x);
    21     }
    22     return ans;
    23 }
    24 void add(int l, int x)
    25 {
    26     while( l <= n )
    27     {
    28         bit[l] += x;
    29         l += lowbit(l);
    30     }
    31 }
    32 int main(int argc, char *argv[])
    33 {
    34     while( scanf("%d", &n) != EOF )
    35     {
    36         int ans = 0;
    37         memset(bit, 0, sizeof(bit));
    38         for( int i = 0 ; i < n ; i++ )
    39         {
    40             scanf("%d", &arr[i]);
    41             ans += i - sum(arr[i]+1);
    42             add(arr[i]+1, 1);
    43         }
    44         int mi = ans;
    45         for( int i = 0 ; i < n ; i++ )
    46         {
    47             ans = ans - arr[i] + n - arr[i] -1;
    48             mi = ans > mi ? mi : ans;
    49         }
    50         printf("%d
    ", mi);
    51     }
    52 }
  • 相关阅读:
    mysql 函数 存储过程 事件(event) job 模板
    protobuf 无proto 解码 decode 语言 java python
    mitmproxy fiddler 抓包 填坑
    android adb 常用命令
    android机器人 模拟 踩坑过程
    RabbitMQ添加新用户并支持远程访问
    Windows下RabbitMQ安装及配置
    Java mybatis mysql 常用数据类型对应关系
    easyExcel 踩坑
    linux防火墙查看状态firewall、iptable
  • 原文地址:https://www.cnblogs.com/jostree/p/4004534.html
Copyright © 2011-2022 走看看