hdu 1394 Minimum Inversion Number
2016-02-17 17:11
260 查看
[align=left]Problem Description[/align]
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.
[align=left]Input[/align]
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.
[align=left]Output[/align]
For each case, output the minimum inversion number on a single line.
[align=left]Sample Input[/align]
[align=left]Sample Output[/align]
[/code]
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.
[align=left]Input[/align]
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.
[align=left]Output[/align]
For each case, output the minimum inversion number on a single line.
[align=left]Sample Input[/align]
10 1 3 6 9 0 8 5 7 4 2
[align=left]Sample Output[/align]
16 我采用线段树解决此问题;每插入一个结点,就检查之前是否有更大的数插入,以此统计逆序对;注意到数字是0到n的一个序列,所以每次将队头的数字移到队尾,逆序对的增减可以找出递推式; [code]#include<iostream> #include<cstdlib> #include<string> #include<algorithm> #include<cstdio> #include<cmath> #include<cstring> #include<stack> #include<queue> #include<iomanip> #include<map> #define pi 3.14159265358979323846 using namespace std; int s[5001]; int tree[20001]; void build(int p,int l,int r) { if(l==r) {tree[p]=0;return;} int mid=(l+r)/2; build(p*2,l,mid); build(p*2+1,mid+1,r); tree[p]=0; } void change(int p,int l,int r,int x,int num) { if(l==r) {tree[p]+=num;return;} int mid=(l+r)/2; if(x<=mid) change(p*2,l,mid,x,num); else change(p*2+1,mid+1,r,x,num); tree[p]=tree[p*2]+tree[p*2+1]; } int find(int p,int l,int r,int x,int y) { if(x<=l&&r<=y) return tree[p]; int mid=(l+r)/2; if(y<=mid) return find(p*2,l,mid,x,y); if(x>mid) return find(p*2+1,mid+1,r,x,y); return (find(p*2,l,mid,x,mid)+find(p*2+1,mid+1,r,mid+1,y)); } int main() { int n; while(scanf("%d",&n)!=EOF) { build(1,1,5000); int ans=0; for(int i=1;i<=n;++i) { scanf("%d",&s[i]); ans+=find(1,1,5000,s[i]+1,5000);//统计逆序对 change(1,1,5000,s[i]+1,1); } int smin=ans; for(int i=1;i<=n;++i) { ans=ans+n-2*s[i]-1;//递推式 if(ans<smin) smin=ans; } printf("%d\n",smin); } return 0; }
[/code]
相关文章推荐
- itext 处理中文问题 Font 'STSong-Light' with 'UniGB-UCS2-H' is not recognized 版本问题
- js.net 多语言&web service 添加服务引用和web 引用
- 目录
- 【python笔记 一 】变量及运算符
- jquery animate实现动态进度条
- 2016.2.17问题总结
- MySQL 初次装时密码为空 为其设置新密码
- 通过Spring Session实现新一代的Session管理
- ng-repeat
- Android进阶笔记13:Android 系统上一款开源的图表库
- SQL语句将某字段查询出以逗号隔开
- ubuntu中redmine局域网内发送邮件提示redmine getaddrinfo: Name or service not known
- Hive - hive.groupby.skewindata环境变量与负载均衡
- haproxy 安装与记录访问日志
- POI操作Excel常用方法总结 (转)
- 图片廊
- 《用户体验要素》读后感
- Road to Django
- java JSONObject对象序列化与反序列化
- RecyclerView 解析