hdu 1394 Minimum Inversion Number 最小逆序数
2015-11-10 22:58
330 查看
Minimum Inversion Number
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 15355 Accepted Submission(s): 9366
Problem Description
The inversion number of a given number sequence a1, a2, ..., an is the number of pairs (ai, aj) that satisfy i < j and ai > aj.
For a given sequence of numbers a1, a2, ..., an, if we move the first m >= 0 numbers to the end of the seqence, we will obtain another sequence. There are totally n such sequences as the following:
a1, a2, ..., an-1, an (where m = 0 - the initial seqence)
a2, a3, ..., an, a1 (where m = 1)
a3, a4, ..., an, a1, a2 (where m = 2)
...
an, a1, a2, ..., an-1 (where m = n-1)
You are asked to write a program to find the minimum inversion number out of the above sequences.
Input
The input consists of a number of test cases. Each case consists of two lines: the first line contains a positive integer n (n <= 5000); the next line contains a permutation of the n integers from 0 to n-1.
Output
For each case, output the minimum inversion number on a single line.
Sample Input
10
1 3 6 9 0 8 5 7 4 2
Sample Output
16
Author
CHEN, Gaoli
Source
ZOJ Monthly, January 2003
Recommend
Ignatius.L | We have carefully selected several similar problems for you: 1166 1698 1540 1542 1255
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int maxn=5000; int n; int a[maxn+20]; int sum[4*maxn+20]; int tot; void update(int num,int le,int ri,int x) { if(le==ri) { sum[num]++; return; } int mid=(le+ri)>>1; if(x<=mid) update(num*2,le,mid,x); else update(num*2+1,mid+1,ri,x); sum[num]=sum[num<<1]+sum[(num<<1)+1]; } int query(int num,int le,int ri,int x,int y) { if(x<=le&&ri<=y) { return sum[num]; } int ret=0; int mid=(le+ri)>>1; if(x<=mid) ret+=query(num*2 ,le ,mid,x,y); if(y> mid) ret+=query(num*2+1,mid+1,ri ,x,y); return ret; } int main() { while(~scanf("%d",&n)) { memset(sum,0,sizeof sum); tot=0; for(int i=1;i<=n;i++) { scanf("%d",&a[i]); tot+=query (1,0,maxn,a[i]+1,maxn); update(1,0,maxn,a[i]); } int mini=tot; for(int i=1;i<=n-1;i++) { int sm=query(1,0,maxn,0,a[i])-1; int la=n-1-sm; tot=tot-sm+la; mini=min(mini,tot); } printf("%d\n",mini); } return 0; }
相关文章推荐
- leetcode之Range Sum Query - Immutable
- hdfs shell命令
- iOS中UIWebview中网页宽度自适应的问题
- lintcode: Sqrt(x)
- 那一年, 我学会了ping命令
- 内存管理1----关闭ARC
- jquery 动态添加元素的事件
- tail /grep/more
- C#学习笔记 委托
- Programming with OC --Defining Classes
- UEFI Console Splitter 2nd
- SSH协议与SSH免登陆
- hdu 1466计算直线的交点数
- LeetCode OJ:Number of 1 Bits(比特1的位数)
- 3D图形学中的透视投影变换 ppt
- pAdPt-0 Android平台(jdk + AS)搭建
- 欢迎使用CSDN-markdown编辑器
- Spring整合JMS(一)——基于ActiveMQ实现
- insmod 内核模块参数传递
- 用R分析时间序列(time series)数据