• 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 }
  • 相关阅读:
    实验17:NAT
    实验16:ACL
    实验15: STP
    实验14:VLAN间的路由
    实验13:VLAN/TRUNK/VTP/
    Linux软件管理--RPM工具
    Linux拓展练习部分--输入输出 / find部分 /基础拓展2
    linux文件管理--压缩打包
    find 文件查找
    防火墙知识点
  • 原文地址:https://www.cnblogs.com/jostree/p/4004534.html
Copyright © 2020-2023  润新知