逆序数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\n", 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\n", res); //从0到n-1的整数 所以这里用a[i] 读题不仔细 。。。。 45 ans = min (sum, ans); 46 } 47 printf ("%d\n", 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\n", 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\n", 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\n", 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\n",Min); 59 } 60 61 return 0; 62 }
树状数组
转载于:https://www.cnblogs.com/Running-Time/p/4492456.html
逆序数2 HDOJ 1394 Minimum Inversion Number相关推荐
- HDU 1394 Minimum Inversion Number(线段树的单点更新)
点我看题目 题意 :给你一个数列,a1,a2,a3,a4.......an,然后可以求出逆序数,再把a1放到an后,可以得到一个新的逆序数,再把a2放到a1后边,,,,,,,依次下去,输出最小的那个逆 ...
- HDU - 1394 Minimum Inversion Number(树状数组)
题目链接:点击查看 题目大意:线段树求逆序数,给出的数列可以组成环,问怎么样求可以让逆序数最小,输出最小值 题目分析:看到这个题的第一反应是暴力枚举5000种情况,因为感觉这个题的N给的不是很大,但是 ...
- HUOJ 1394 Minimum Inversion Number
本题两种解法,暴搜,线段树,线段树只是处理最初序列,找出最初的逆序数,之后每次移动为当前逆序数+比移动数大的数-比移动数小的数. 做本题时完全没有想法,完全没有~copy胡浩大神代码,第一次抄错题.. ...
- HDOJ1394 Minimum Inversion Number【线段树】
需要注意的就是给出的数是0~n-1,而线段树根节点范围是1-n 所以main中insert要num[i]+1. 当然,根节点范围换成0~n-1就不需要了. Problem : 1394 ( Minim ...
- Minimum Inversion Number HDU - 1394(求一个数字环的逆序对+多种解法)
题意: 给出n个数(0~n-1,每个数仅出现一次),问它长为n的循环序列中逆序对最少的数量. 多种解法:暴力+树状数组+分治+规律推导公式 题目: The inversion number of a ...
- 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 ...
- [HDU1394]Minimum Inversion Number
题目:Minimum Inversion Number 链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394 分析: 1)先对序列求逆序对的数目,归并排序 ...
- Minimum Inversion Number 线段树
The inversion number of a given number sequence a1, a2, -, an is the number of pairs (ai, aj) that s ...
- hdu1394 Minimum Inversion Number 线段树和树状数组
题意: 输入一个长度 n 第二行给出长度为n的数组,数组的值刚好为0到n-1这n个数. 然后每次把数组的第一个数放到最后一个,放n-1次,共有n个排列,这n个排列就有n个逆序数,输出这n个逆序数的最小 ...
最新文章
- linux===Ubuntu 上安装 Node.js
- Android发送邮件
- 水泵怎么做_泳池设备日常怎么维护和保养?
- [渝粤教育] 西南科技大学 计算机网络应用基础 在线考试复习资料2021版(1)
- android getter不起作用,java - 如何在Android Studio中自动生成getter和setter
- 林辉高考机器人_机器人2019年参加高考 力争考上一本
- PTA16、列表元素个数的加权和(1) (10 分)
- 向量空间模型(VSM)--用于计算文本相似度
- 淺談auto_ptr
- POJ 1275 Cashier Employment
- 【数字信号调制】基于matlab GUI数字信号调制系统【含Matlab源码 258期】
- SQL Server 聚合函数 (方差和标准差)
- 伺服电机PID控制及增益调节
- 无线传感器网络(双语)复习
- ad7606中文资料_AD7606
- 微信支付当前页面的URL未注册问题[单页面]
- java如何在窗口上显示数据_如何把Java程序窗口在屏幕中间显示
- 阿里云ECS服务器的wordpress博客域名购买、认证、备案、解析以及绑定
- 宠物领养系统C语言代码,基于JavaEE的宠物领养系统的设计与实现毕业论文+任务书+中期表+外文翻译及原文+答辩PPT+项目源码及数据库+运行说明...
- 三国演义java_三国演义全集高清_java进阶(34)–File类、目录复制
热门文章
- centos7.6+vim8.1
- namenode与datanode
- Linux下mknod的作用,Linux系统mknod命令用法
- java 读utf-8 xml_〖JAVA经验〗JDom输出UTF-8的XML完美解决方法
- 人工智能的炒作_解密人工智能:是炒作还是我们期望太高
- dxf转pdf linux,4个最好的PDF转DXF格式的在线转换器
- 【存储知识学习】第三章磁盘原理与技术3.10 固态存储介质和固态硬盘-《大话存储》阅读笔记
- 2019春季暑期实习生正式批招聘笔试【腾讯】(回忆版)第一题
- Winform中使用用户控件实现带行数和标尺的RichTextBox(附代码下载)
- C#中File类的常用读取与写入文件方法的使用