• 【HDOJ】1394 Minimum Inversion Number


    逆序数的性质。
    1. 暴力解

     1 #include <stdio.h>
     2 
     3 #define MAXNUM 5005
     4 
     5 int a[MAXNUM];
     6 
     7 int main() {
     8     int n;
     9     int i, j, sum, min;
    10 
    11     while (scanf("%d", &n) != EOF) {
    12         for (i=0; i<n; ++i)
    13             scanf("%d", &a[i]);
    14         sum = 0;
    15         for (i=0; i<n; ++i) {
    16             for (j=i+1; j<n; ++j)
    17                 if (a[j] < a[i])
    18                     ++sum;
    19         }
    20         min = sum;
    21         for (i=0; i<n; ++i) {
    22             sum += n - 1 - a[i]*2;
    23             if (sum < min)
    24                 min = sum;
    25             //printf("%d
    ", sum);
    26         }
    27         printf("%d
    ", min);
    28     }
    29 
    30     return 0;
    31 }

    2. 线段树。需要理解如何求逆序数。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 using namespace std;
     5 
     6 #define lson l, m, rt<<1
     7 #define rson m+1, r, rt<<1|1
     8 
     9 const int maxn = 5005;
    10 
    11 int nums[maxn<<2];
    12 int a[maxn];
    13 
    14 void PushUP(int rt) {
    15     nums[rt] = nums[rt<<1] + nums[rt<<1|1];
    16 }
    17 
    18 void build(int l, int r, int rt) {
    19     nums[rt] = 0;
    20     if (l == r) return;
    21     int m = (l+r)>>1;
    22     build(lson);
    23     build(rson);
    24 }
    25 
    26 void update(int p, int l, int r, int rt) {
    27     if (l == r) {
    28         nums[rt] = 1;
    29         return ;
    30     }
    31     int m = (l+r)>>1;
    32     if (p <= m)
    33         update(p, lson);
    34     else
    35         update(p, rson);
    36     PushUP(rt);
    37 }
    38 
    39 int query(int ll, int rr, int l, int r, int rt) {
    40     if (ll<=l && rr>=r) {
    41         return nums[rt];
    42     }
    43     int m = (l+r)>>1;
    44     int ret = 0;
    45     if (ll <= m)
    46         ret += query(ll, rr, lson);
    47     if (rr > m)
    48         ret += query(ll, rr, rson);
    49 
    50     return ret;
    51 }
    52 
    53 int main() {
    54     int n;
    55     int i, sum, min;
    56 
    57     while (scanf("%d", &n) != EOF) {
    58         build(0, n-1, 1);
    59         sum = 0;
    60         for (i=0; i<n; ++i) {
    61             scanf("%d", &a[i]);
    62             sum += query(a[i], n-1, 0, n-1, 1);
    63             update(a[i], 0, n-1, 1);
    64             //printf("%d: sum=%d
    ", i, sum);
    65         }
    66         min = sum;
    67         for (i=0; i<n; ++i) {
    68             sum += n - 1 - a[i]*2;
    69             if (sum < min)
    70                 min = sum;
    71         }
    72         printf("%d
    ", min);
    73     }
    74 
    75     return 0;
    76 }
  • 相关阅读:
    Android ListView 列表视图
    android handler msg的使用 实现进度条
    Intent 传递数据
    微服务-springcloud
    微服务-dubbo学习
    日志收集系统
    微服务追踪
    链表有环判断,快慢指针两种方法/合并链表/删除重复元素/二分递归和while
    算法练习,链表二分最大n个
    池以及barrier简单
  • 原文地址:https://www.cnblogs.com/bombe1013/p/3761381.html
Copyright © 2020-2023  润新知