hdu1394(树状数组)最小逆序对数
2018-01-31 02:39
344 查看
Minimum Inversion Number
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 22426 Accepted Submission(s): 13351
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
4000
Recommend
Ignatius.L | We have carefully selected several similar problems for you: 1698 1540 1542 1255 1754
#include<iostream> #include<cstdio> #include<string> #include<queue> #include<stack> #include<map> #include<vector> #include<list> #include<set> #include<iomanip> #include<cstring> #include<cctype> #include<cmath> #include<cstdlib> #include<ctime> #include<cassert> #include<sstream> #include<algorithm> using namespace std; const int MAXN = 10005; #define MOD 1000000007 #define INF 0x3f3f3f3f #define PI numcos(-1.0) typedef long long ll; int c[MAXN],num[MAXN],n; int lowbit(int i) { return i&(-i); } void add(int i,int value) { while(i<=n) { c[i]+=value; i+=lowbit(i); } } int sum(int i) { int sum=0; while(i>0) { sum+=c[i]; i-=lowbit(i); } return sum; } int main() { while(~scanf("%d",&n)) { memset(c,0,sizeof(c)); for(int i=0; i<n; i++) scanf("%d",&num[i]); int ans=0,tp; for(int i=0; i<n; i++)//n-num[i]表示比num[i]大的数有多少个 { ans+=sum(n-num[i]);//当前num[i]的逆序对数有多少 add(n-num[i],1);// } tp=ans; for(int i=0; i<n-1; i++) { add(n-num[i],-1);//把第一个数字从所放位置拿掉 tp=tp+sum(n-num[i])-num[i]; //原逆序对数+第一个数字放在最后一位上时能产生的逆序对数-第一位以后有多少个比第一位小的数字数目 add(n-num[i],1);//数字放回 if(ans>tp) ans=tp; } printf("%d\n",ans); } return 0; }
相关文章推荐
- hdu1394 Inversion后的最小逆序数 线段树 树状数组
- Ultra-QuickSort 求最小交换次数即求逆序对数 树状数组+离散化
- Ultra-QuickSort 求最小交换次数即求逆序对数 树状数组+离散化
- Ultra-QuickSort 求最小交换次数即求逆序对数 树状数组+离散化
- HDU 1394 Minimum Inversion Number (最小逆序对数&线段树)
- Ultra-QuickSort 求最小交换次数即求逆序对数 树状数组+离散化
- hdu1394最小逆序数——线段树
- Ultra-QuickSort 求最小交换次数即求逆序对数 树状数组+离散化
- Ultra-QuickSort 求最小交换次数即求逆序对数 树状数组+离散化
- Ultra-QuickSort 求最小交换次数即求逆序对数 树状数组+离散化
- Ultra-QuickSort 求最小交换次数即求逆序对数 树状数组+离散化
- 求逆序对数的方法(归并排序 and 树状数组)
- Ultra-QuickSort 求最小交换次数即求逆序对数 树状数组+离散化
- HDU1394最小逆序数
- Ultra-QuickSort 求最小交换次数即求逆序对数 树状数组+离散化
- 求逆序对数的NLogN解法:归并排序、树状数组和线段树
- hdu 4911 求逆序对数+树状数组
- Ultra-QuickSort 求最小交换次数即求逆序对数 树状数组+离散化
- hdu 4911 求逆序对数+树状数组
- Ultra-QuickSort 求最小交换次数即求逆序对数 树状数组+离散化