zoukankan      html  css  js  c++  java
  • 逆序数2 HDOJ 1394 Minimum Inversion Number

    题目传送门

    1 /*
    2     求逆序数的四种方法
    3 */
     1 /*
     2     1. O(n^2) 暴力+递推 法:如果求出第一种情况的逆序列,其他的可以通过递推来搞出来,一开始是t[1],t[2],t[3]....t[N]
     3     它的逆序列个数是N个,如果把t[1]放到t[N]后面,逆序列个数会减少t[1]个,相应会增加N-(t[1]+1)个  
     4 */
     5 #include <cstdio>
     6 #include <cstring>
     7 #include <algorithm>
     8 using namespace std;
     9 
    10 const int MAX_N = 10000 + 10;
    11 const int INF = 0x3f3f3f3f;
    12 int a[MAX_N];
    13 int num[MAX_N];
    14 
    15 int main(void)      //HDOJ 1394 Minimum Inversion Number
    16 {
    17     //freopen ("inC.txt", "r", stdin);
    18     int n;
    19 
    20     while (~scanf ("%d", &n))
    21     {
    22         memset (num, 0, sizeof (num));
    23         for (int i=1; i<=n; ++i)
    24         {
    25             scanf ("%d", &a[i]);
    26             //a[n+i] = a[i];
    27         }
    28         int t = 0;  int sum = 0;
    29         for (int i=1; i<=n; ++i)    //先求解最初的数列逆序数
    30         {
    31             for (int j=i+1; j<=n; ++j)
    32             {
    33                 if (a[i] > a[j])
    34                 {
    35                     sum++;
    36                 }
    37             }
    38         }
    39         //printf ("%d
    ", sum);
    40         int ans = INF;
    41         for (int i=1; i<=n; ++i)        //更新sum,找最小
    42         {
    43             sum = sum - a[i] + (n - a[i] - 1);      //the next line contains a permutation of the n integers from 0 to n-1. 
    44             //printf ("%d
    ", res);                 //从0到n-1的整数  所以这里用a[i]  读题不仔细 。。。。
    45             ans = min (sum, ans);
    46         }
    47         printf ("%d
    ", ans);
    48     }
    49 
    50     return 0;
    51 }
    O(n^2) 暴力+递推
     1 /*
     2     2. 归并算法
     3 */
     4 #include <cstdio>
     5 #include <algorithm>
     6 using namespace std;
     7 
     8 const int MAX_N = 10000 + 10;
     9 const int INF = 0x3f3f3f3f;
    10 int a[MAX_N];
    11 int b[MAX_N];
    12 int L[MAX_N/2+10], R[MAX_N/2+10];
    13 int cnt = 0;
    14 
    15 void Merge(int *a, int p, int q, int r)
    16 {
    17     int n1 = q - p + 1;
    18     int n2 = r - q;
    19     int i, j;
    20 
    21     for (i=1; i<=n1; ++i)
    22     {
    23         L[i] = a[p+i-1];
    24     }
    25     for (j=1; j<=n2; ++j)
    26     {
    27         R[j] = a[q+j];
    28     }
    29     L[n1+1] = R[n2+1] = INF;
    30     i = j = 1;
    31     for (int k=p; k<=r; ++k)
    32     {
    33         if (L[i] <= R[j])
    34         {
    35             a[k] = L[i++];
    36         }
    37         else
    38         {
    39             a[k] = R[j++];
    40             cnt += n1 - i + 1;
    41         }
    42     }
    43 }
    44 
    45 void MergeSort(int *a, int p, int r)
    46 {
    47     if (p < r)
    48     {
    49         int q = (p + r) / 2;
    50         MergeSort (a, p, q);
    51         MergeSort (a, q+1, r);
    52         Merge (a, p, q, r);
    53     }
    54 }
    55 
    56 int main(void)      //HDOJ 1394 Minimum Inversion Number
    57 {
    58     //freopen ("inC.txt", "r", stdin);
    59     int n;
    60     while (~scanf ("%d", &n) && n)
    61     {
    62         for (int i=1; i<=n; ++i)
    63         {
    64             scanf ("%d", &a[i]);
    65             b[i] = a[i];
    66         }
    67         MergeSort (a, 1, n);
    68         //printf ("%d
    ", cnt);
    69         int ans = INF;
    70         for (int i=1; i<=n; ++i)        //注意a[i]已排序
    71         {
    72             cnt = cnt - b[i] + (n - b[i] - 1);
    73             ans = min (cnt, ans);
    74         }
    75         printf ("%d
    ", ans);
    76         cnt = 0;
    77     }
    78 
    79     return 0;
    80 }
    nlogn 归并排序
     1 /*
     2     3. nlogn 线段树-单点更新:更新比a[i]大的个数
     3 */
     4 #include <cstdio>
     5 #include <algorithm>
     6 #define lson l, m, rt << 1
     7 #define rson m+1, r, rt << 1 | 1
     8 
     9 const int MAX_N = 5000 + 10;
    10 const int INF = 0x3f3f3f3f;
    11 int a[MAX_N];
    12 int sum[MAX_N << 2];
    13 
    14 void pushup(int rt)
    15 {
    16     sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
    17 }
    18 
    19 void build(int l, int r, int rt)
    20 {
    21     sum[rt] = 0;
    22     if (l == r) return ;
    23     int m = (l + r) >> 1;
    24     build (lson);
    25     build (rson);
    26 }
    27 
    28 void update(int p, int l, int r, int rt)
    29 {
    30     if (l == r)
    31     {
    32         sum[rt]++;      //记录次数
    33         return ;
    34     }
    35     int m = (l + r) >> 1;
    36     if (p <= m)
    37     {
    38         update (p, lson);
    39     }
    40     else
    41         update(p, rson);
    42     pushup (rt);
    43 }
    44 
    45 int query(int ql, int qr, int l, int r, int rt)
    46 {
    47     if (ql <= l && r <= qr)
    48     {
    49         return sum[rt];
    50     }
    51     int m = (l + r) >> 1;
    52     int ans = 0;
    53     if (ql <= m)    ans += query (ql, qr, lson);
    54     if (qr > m)     ans += query (ql, qr, rson);
    55 
    56     return ans;
    57 }
    58 
    59 int main(void)      //HDOJ 1394 Minimum Inversion Number
    60 {
    61     //freopen ("inC.txt", "r", stdin);
    62     int n;
    63     while (~scanf ("%d", &n))
    64     {
    65         //memset (num, 0, sizeof (num));
    66         build (0, n-1, 1);
    67         int sum = 0;
    68         for (int i=1; i<=n; ++i)   
    69         {
    70             scanf ("%d", &a[i]);
    71             sum += query (a[i], n-1, 0, n-1, 1);
    72             update (a[i], 0, n-1, 1);
    73         }
    74         int ans = sum;
    75         for (int i=1; i<=n; ++i)        
    76         {
    77             sum = sum - a[i] + (n - a[i] - 1);            
    78             ans = std::min (sum, ans);
    79         }
    80         printf ("%d
    ", ans);
    81     }
    82 
    83     return 0;
    84 }
    nlogn 线段树-单点更新
     1 /*
     2     4. 树状数组
     3 */
     4 #include <stdio.h>
     5 #include <string.h>
     6 #include <algorithm>
     7 using namespace std;
     8 const int MAXN=5050;
     9 int c[MAXN];
    10 int a[MAXN];
    11 int n;
    12 
    13 int lowbit(int x)
    14 {
    15     return x&(-x);
    16 }
    17 
    18 void add(int i,int val)
    19 {
    20     while(i<=n)
    21     {
    22         c[i]+=val;
    23         i+=lowbit(i);
    24     }
    25 }
    26 
    27 int sum(int i)
    28 {
    29     int s=0;
    30     while(i>0)
    31     {
    32         s+=c[i];
    33         i-=lowbit(i);
    34     }
    35     return s;
    36 }
    37 
    38 int main()      //HDOJ 1394 Minimum Inversion Number
    39 {
    40     //freopen ("inC.txt", "r", stdin);
    41     while(scanf("%d",&n)!=EOF)
    42     {
    43         int ans=0;
    44         memset(c,0,sizeof(c));
    45         for(int i=1;i<=n;i++)
    46         {
    47             scanf("%d",&a[i]);
    48             a[i]++;
    49             ans+=sum(n)-sum(a[i]);
    50             add(a[i],1);
    51         }
    52         int Min=ans;
    53         for(int i=1;i<=n;i++)
    54         {
    55             ans+=n-a[i]-(a[i]-1);
    56             if(ans<Min)Min=ans;
    57         }
    58         printf("%d
    ",Min);
    59     }
    60     
    61     return 0;
    62 }
    树状数组



    编译人生,运行世界!
  • 相关阅读:
    js正则表达式,判断字符串是否以数字组结尾,并取出结尾的数字
    js中的正则表达式入门
    jQuery获取元素对象本身的html
    正则表达式,求判断字符串是否以数字组结尾,并取出结尾的数字 正则表达式
    行为树的设计与实现
    BMFONT 字体制作
    VMware 9.0.1安装Mac OS X Mountain Lion 10.8.2
    XCODE修改IOS应用的名称
    Xcode 生成 ipa包
    Xcode 打包 ipa 包
  • 原文地址:https://www.cnblogs.com/Running-Time/p/4492456.html
Copyright © 2011-2022 走看看