HDU-1394-Minimum Inversion Number树状数组
来源:互联网 发布:成都网络综合布线 编辑:程序博客网 时间:2024/06/08 04:49
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
给一个整数n,接下来有n个数。每次将第一个值放到该数列的最后,循环n次。
对于每一次变换求它的逆序数,找出最小值。
首先要用树状数组来求逆序数。
其次,
假设每次移动的值为a[i]
对于每一次状态变换而言:当前的逆序数=上个状态的逆序数+a-(b-1)
a是指当前序列中比a[i]大的数;
(b-1)是指当前序列中比a[i]小的数。
因为每一次把a[i]移动到最后的时候,比他大的数原本不构成逆序对,但是移动到最后构成了逆序对,所以要加比它大的数。同理,原本比它小的数构成逆序对,但是移动到最后不够成逆序对,所以要减去。
OVER!
贴代码
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;typedef long long int LL;const int MAXL(500000);struct node{ int x; int order;} s[MAXL+50];int c[MAXL+50];int dis[MAXL+50];//这里离散化了一下数组,但是本题数据量小,没有必要。int n;bool cmp(struct node p,struct node q){ return p.x<q.x;}int lowbit(int k){ return k&(-k);}void Update(int i,int value){ while(i<=n) { c[i]+=value; i+=lowbit(i); }}int Getsum(int i){ int ans=0; while(i>0) { ans+=c[i]; i-=lowbit(i); } return ans;}int min(int x,int y){ return x>y?y:x;}int main(){ while(~scanf("%d",&n)) { memset(c,0,sizeof(c)); for(int i=1; i<=n; i++) { scanf("%d",&s[i].x); s[i].order=i; } sort(s+1,s+n+1,cmp); for(int i=1; i<=n; i++) dis[s[i].order]=i; LL ans=0; for(int i=1; i<=n; i++) { Update(dis[i],1); ans+=i-Getsum(dis[i]); } int MIN=ans; for(int i=1;i<=n;i++) { ans=ans+(n-dis[i])-(dis[i]-1); MIN=min(MIN,ans); } cout<<MIN<<endl; }}
- HDU 1394 Minimum Inversion Number 树状数组
- hdu 1394 Minimum Inversion Number (树状数组)
- HDU 1394 Minimum Inversion Number(树状数组)
- HDU-1394 Minimum Inversion Number 树状数组
- HDU 1394 Minimum Inversion Number 树状数组
- HDU 1394 Minimum Inversion Number 树状数组
- HDU 1394 Minimum Inversion Number(树状数组)
- Minimum Inversion Number - HDU 1394 树状数组
- hdu 1394 Minimum Inversion Number(树状数组)
- hdu 1394 Minimum Inversion Number(树状数组)
- HDU 1394 Minimum Inversion Number (树状数组)
- hdu 1394 Minimum Inversion Number(树状数组)
- HDU 1394 Minimum Inversion Number(树状数组)
- HDU-1394 Minimum Inversion Number 树状数组
- hdu-1394-Minimum Inversion Number(树状数组)
- HDU 1394 Minimum Inversion Number 树状数组
- HDU 1394 Minimum Inversion Number 树状数组
- HDU-1394-Minimum Inversion Number树状数组
- C++函数的返回值(下)
- 7.log4j2的使用
- LightOJ
- 方法参数
- python-正则表达式
- HDU-1394-Minimum Inversion Number树状数组
- ORA-01691: unable to extend lob segment 问题解决
- 普通程序员如何入门深度学习?
- centos环境下如何配置yum源
- sql monitor 实践
- Java将图片处理成背景透明的圆形图片
- Linux下vim的常用命令
- first_report_gu
- C++ 继承、虚继承、虚函数类内存分配