【数列上的分治】——hdu2689
Sort it
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3938 Accepted Submission(s): 2791
Problem Description
You want to processe a sequence of n distinct integers by swapping two adjacent sequence elements until the sequence is sorted in ascending order. Then how many times it need.
For example, 1 2 3 5 4, we only need one operation : swap 5 and 4.
For example, 1 2 3 5 4, we only need one operation : swap 5 and 4.
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 <= 1000); the next line contains a permutation of the n integers from 1 to n.
Output
For each case, output the minimum times need to sort it in ascending order on a single line.
Sample Input
3
1 2 3
4
4 3 2 1
Sample Output
0
6
Author
WhereIsHeroFrom
题意:求逆序数
思路:把数列分成两半
则逆序对变成了三种:
(1)i,j都在b内
(2)i,j都在c内
(3)i,j一个在b内,一个在c内
前两种:递归的时候就包含在上一层的cnt内了
第三种:归并排序的时候计算即可。
附上代码:
//利用归并排序 #include<iostream> #include<vector> using namespace std; typedef long long ll; ll merge_count(vector<int> &a) { if(a.size()<=1)return 0; ll cnt=0; vector<int> b(a.begin() , a.begin()+a.size()/2); vector<int> c(a.begin()+a.size()/2 , a.end() ); cnt+=merge_count(b);//(1) cnt+=merge_count(c);//(2) //此时,b,c已经排好序了 //归并排序 //(3) int ai=0,bi=0,ci=0; while(ai<a.size()) { //非逆序 if(bi<b.size() && (ci==c.size() || b[bi]<=c[ci]) ) { a[ai++]=b[bi++]; } //逆序 else { cnt+=a.size()/2 - bi; a[ai++]=c[ci++]; } } return cnt; } int main() { int t; while(cin>>t) { vector<int>A;//注意vector初始化的位置 int num; for(int i=0;i<t;i++) { cin>>num; A.push_back(num); } cout<<merge_count(A)<<endl; } return 0; }

浙公网安备 33010602011771号