zoukankan      html  css  js  c++  java
  • HDU1394 Minimum Inversion Number

      原题传送:http://acm.hdu.edu.cn/showproblem.php?pid=1394

      求逆序数。

      题目上来一看,发现直接暴力可过,复杂度O(n2),300+ms,代码简短得要命:

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

      其实这道题复杂度都耗在了第一次求总逆序数上了,后来想想,发现可以用nlog(n)的归并排序搞,15~30ms。

    View Code
     1 #include <stdio.h>
     2 #define N 5005
     3 int a[N], b[N], c[N];
     4 
     5 inline int min(int x, int y)
     6 {
     7     return x < y ? x : y;
     8 }
     9 
    10 int cal(int s, int t)
    11 {
    12     int i, j, k, mid;
    13     int res;
    14     if(t - s == 1)
    15         return 0;
    16     mid = (s + t) >> 1;
    17     res = cal(s, mid) + cal(mid, t);
    18     i = s, j = mid, k = s;
    19     while(i < mid && j < t)
    20     {
    21         if(a[i] <= a[j])
    22             b[k ++] = a[i ++], res += j - mid;
    23         else
    24             b[k ++] = a[j ++];
    25     }
    26     while(i < mid) b[k ++] = a[i ++], res += j - mid;
    27     while(j < t) b[k ++] = a[j ++];
    28     for(i = 0; i < t - s; i ++)
    29         a[s + i]= b[s + i];
    30     return res;
    31 }
    32 
    33 int main()
    34 {
    35     int i, n, ans, m;
    36     while(scanf("%d", &n) != EOF)
    37     {
    38         for(i = 1; i <= n; i ++)
    39         {
    40             scanf("%d", &a[i]);
    41             c[i] = a[i];
    42         }
    43         ans = cal(1, n + 1);
    44         m = ans;
    45         for(i = 1; i < n; i ++)
    46             ans = min(ans, m = m + n - c[i] - 1 - c[i]);
    47         printf("%d\n", ans);
    48     }
    49     return 0;
    50 }

      其实我是想用线段树写的,30ms。

    View Code
     1 #include <stdio.h>
     2 #include <string.h>
     3 #define lson (cur << 1)
     4 #define rson (cur << 1 | 1)
     5 #define N 5005
     6 
     7 int tree[N << 2], a[N];
     8 
     9 inline int min(int x, int y)
    10 {
    11     return x < y ? x : y;
    12 }
    13 
    14 void pushup(int cur)
    15 {
    16     tree[cur] = tree[lson] + tree[rson];
    17 }
    18 
    19 void query(int cur, int l, int r, int x, int y, int &ans)
    20 {
    21     if(l >= x && r <= y)
    22     {
    23         ans += tree[cur];
    24         return ;
    25     }
    26     int mid = (l + r) >> 1;
    27     if(mid >= x)
    28         query(lson, l, mid, x, y, ans);
    29     if(mid + 1 <= y)
    30         query(rson, mid + 1, r, x, y, ans);
    31 }
    32 
    33 void update(int cur, int l, int r, int loc)
    34 {
    35     if(l == r)
    36     {
    37         tree[cur] = 1;
    38         return ;
    39     }
    40     int mid = (l + r) >> 1;
    41     if(mid >= loc)
    42         update(lson, l, mid, loc);
    43     else
    44         update(rson, mid + 1, r, loc);
    45     pushup(cur);
    46 }
    47 
    48 int main()
    49 {
    50     int n, i, v, ans, sum;
    51     while(scanf("%d", &n) != EOF)
    52     {
    53         memset(tree, 0, sizeof tree);
    54         for(sum = 0, i = 1; i <= n; i ++)
    55         {
    56             scanf("%d", &a[i]);
    57             v = 0;
    58             query(1, 1, n, a[i] + 1, n, v);
    59             sum += v;
    60             update(1, 1, n, a[i]);
    61         }
    62         ans = sum;
    63         for(i = 1; i < n; i ++)
    64             ans = min(ans, sum = sum + n - a[i] - 1 - a[i]);
    65         printf("%d\n", ans);
    66     }
    67     return 0;
    68 }
  • 相关阅读:
    解决SharePoint 2010拒绝访问爬网内容源错误
    Sharepoint 2010 工作流状态值
    修改任务显示WrkTaskIp.aspx页面
    Infopath 2013 通过UserProfileService读取AD用户信息
    js验证
    .net中下载文件的方法(转)
    IIS限制ASP.Net 文件上传大小解决方案,修改IIS7/7.5配置
    SharePoint2013 SharePoint-Hosted 模式 分页方法
    技术QQ群
    react学习
  • 原文地址:https://www.cnblogs.com/huangfeihome/p/2700648.html
Copyright © 2011-2022 走看看