题意:

  输入一个长度 n

  第二行给出长度为n的数组,数组的值刚好为0到n-1这n个数。

然后每次把数组的第一个数放到最后一个,放n-1次,共有n个排列,这n个排列就有n个逆序数,输出这n个逆序数的最小值。

我的做法:

1、每次输入a[i]后,都把a[i] ++;

2、求出第一个排列的逆序数

3、递推求出所有的逆序数

那怎么求1呢?

对于每一个a[i],求出1到i-1 中比它大的个数,然后相加,即可得。若用朴素的查找,肯定会超时的,所以这里就利用线段树或者树状数组来快速查找。

线段树版本:

 1 #include<cstdio>
 2 #include<cstring>
 3 #define lson l,m,rt<<1
 4 #define rson m+1,r,rt<<1|1
 5 const int maxn=5010;
 6 int c[maxn<<2];
 7 int a[maxn];
 8 int sum[maxn];
 9 void pushup(int rt)
10 {
11     c[rt]=c[rt<<1]+c[rt<<1|1];
12 }
13 void update(int p,int add,int l,int r,int rt)
14 {
15     if(l==r){
16         c[rt]+=add;
17         return;
18     }
19     int m=(l+r)>>1;
20     if(p<=m)
21         update(p,add,lson);
22     else
23         update(p,add,rson);
24     pushup(rt);
25 }
26 int query(int L,int R,int l,int r,int rt)
27 {
28     if(L<=l&&R>=r)
29         return c[rt];
30     int m=(l+r)>>1;
31     int ret=0;
32     if(L<=m)
33         ret+=query(L,R,lson);
34     if(R>m)
35         ret+=query(L,R,rson);
36     return ret;
37 }
38 int main()
39 {
40     int n;
41     while(scanf("%d",&n)!=EOF){
42         sum[1]=0;
43         memset(c,0,sizeof(c));
44         for(int i=1;i<=n;i++){
45             scanf("%d",&a[i]);
46             a[i]++;
47             sum[1]+=query(a[i],n,1,n,1);
48             update(a[i],1,1,n,1);
49         }
50         for(int i=2;i<=n;i++)
51             sum[i]=sum[i-1]+n+1-2*a[i-1];
52         int ans=n*n;
53         for(int i=1;i<=n;i++)
54             if(sum[i]<ans)
55                 ans=sum[i];
56         printf("%d\n",ans);
57     }
58     return 0;
59 }

View Code

用了46ms

树状数组版本:

 1 #include<cstdio>
 2 #include<cstring>
 3 const int maxn=5010;
 4 int c[maxn];
 5 int a[maxn];
 6 int sum[maxn];
 7 int lowbit(int x)
 8 {
 9     return x&(-x);
10 }
11 void update(int x,int d,int n)
12 {
13     while(x<=n){
14         c[x]+=d;
15         x+=lowbit(x);
16     }
17 }
18 int query(int x)
19 {
20     int ret=0;
21     while(x>0){
22         ret+=c[x];
23         x-=lowbit(x);
24     }
25     return ret;
26 }
27 int main()
28 {
29     int n;
30     while(scanf("%d",&n)!=EOF){
31         memset(c,0,sizeof(c));
32         sum[1]=0;
33         for(int i=1;i<=n;i++){
34             scanf("%d",&a[i]);
35             a[i]++;
36             sum[1]+=(i-1-query(a[i]));
37             update(a[i],1,n);
38         }
39         for(int i=2;i<=n;i++)
40             sum[i]=sum[i-1]+n+1-2*a[i-1];
41         int ans=n*n;
42         for(int i=1;i<=n;i++)
43             if(ans>sum[i])
44                 ans=sum[i];
45         printf("%d\n",ans);
46     }
47     return 0;
48 }

View Code

也是46ms

转载于:https://www.cnblogs.com/-maybe/p/4355340.html

hdu1394 Minimum Inversion Number 线段树和树状数组相关推荐

  1. Minimum Inversion Number 线段树

    The inversion number of a given number sequence a1, a2, -, an is the number of pairs (ai, aj) that s ...

  2. [HDU1394]Minimum Inversion Number

    题目:Minimum Inversion Number 链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394 分析: 1)先对序列求逆序对的数目,归并排序 ...

  3. Minimum Inversion Number HDU - 1394(权值线段树/树状数组)

    The inversion number of a given number sequence a1, a2, -, an is the number of pairs (ai, aj) that s ...

  4. HDOJ1394 Minimum Inversion Number【线段树】

    需要注意的就是给出的数是0~n-1,而线段树根节点范围是1-n 所以main中insert要num[i]+1. 当然,根节点范围换成0~n-1就不需要了. Problem : 1394 ( Minim ...

  5. 逆序数2 HDOJ 1394 Minimum Inversion Number

    题目传送门 1 /* 2 求逆序数的四种方法 3 */ 1 /* 2 1. O(n^2) 暴力+递推 法:如果求出第一种情况的逆序列,其他的可以通过递推来搞出来,一开始是t[1],t[2],t[3]. ...

  6. Minimum Inversion Number HDU - 1394(求一个数字环的逆序对+多种解法)

    题意: 给出n个数(0~n-1,每个数仅出现一次),问它长为n的循环序列中逆序对最少的数量. 多种解法:暴力+树状数组+分治+规律推导公式 题目: The inversion number of a ...

  7. HDU - 1394 Minimum Inversion Number(树状数组)

    题目链接:点击查看 题目大意:线段树求逆序数,给出的数列可以组成环,问怎么样求可以让逆序数最小,输出最小值 题目分析:看到这个题的第一反应是暴力枚举5000种情况,因为感觉这个题的N给的不是很大,但是 ...

  8. HD1394 Minimum Inversion Number

    这道题目的意思是:给你一个序列,统计一开始的逆序数的个数,然后依次把第一个元素放到序列末尾,求每次的逆序数个数,求出每次求逆序数里,逆序数最小的那个数 这里需要推一个递推式,就是每次你把第一个元素放到 ...

  9. HDU 1394 Minimum Inversion Number(线段树的单点更新)

    点我看题目 题意 :给你一个数列,a1,a2,a3,a4.......an,然后可以求出逆序数,再把a1放到an后,可以得到一个新的逆序数,再把a2放到a1后边,,,,,,,依次下去,输出最小的那个逆 ...

最新文章

  1. 网易青果后端系统设计窥探(含直播方案踩坑往事)
  2. git-ftp Can't access remote 'ft://...', exiting...问题记录
  3. css html 双面打印_从 Linux 命令行进行打印 | Linux 中国
  4. springmvc是什么_SpringBoot与SpringMVC的区别是什么?
  5. mysql中字符串拼接函数_MySQL字符串连接函数
  6. 每日小记 2017.3.24
  7. DL_C2_week1_1(Initialization)神经网络模型的初始化
  8. steam账号被盗找回概率_如何找回忘记的Steam密码
  9. WinSCP(Windows与Linux文件同步工具)使用总结
  10. ART模式下dex2oat出错导致系统无法正常启动
  11. 2021-2027全球与中国陶瓷基板市场现状及未来发展趋势
  12. 什么是鱼骨分析法(N Why)?
  13. jeecms 取附件
  14. nginx 客户端返回499的错误码
  15. 网页设计师和网页前端开发我该选择哪一个
  16. Jay的小迷弟-字符串溢出处理取模例题
  17. 阿里云Ubuntu 18.04安装图形界面
  18. Linux_Linux_sort 命令
  19. 今日头条自媒体视频搬运,视频去/消重技术软件/不重复视频教程 头条消重去重复视频教程自媒体进阶...
  20. 近期想跳槽的程序员必看!2021最新京东Java面试题目

热门文章

  1. 【Python-ML】无监督线性降维PCA方法
  2. SSH客户端开发开源组件Ganymed SSH-2 for Java初体验
  3. 机器学习知识点(二十)矩阵奇异值分解基础知识及Java实现
  4. (转载)Google Analytics(Google分析)使用技巧
  5. Pandas缺失数据最快定位方式(极少代码快速实现,打死不用循环!!!!!)
  6. 声明式事务--@EnableTransactionManagement || @Transactional
  7. jQuery 里面的排他思想
  8. const的使用 || 对象增强写法 (对象字面量)
  9. C++——构造函数析构函数
  10. CTFshow 反序列化 web273