题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394
理解了归并排序,学习了一下别人的博客,有把这个题目给敲了一遍。。。
这道题我用归并排序是我目前过的最快的算法62ms。。。当然,在我得博客里也有有线段树和树状数组求逆序数的模板;
这里我就没有离散化,还不能算是所有逆序数的模板。。。
对于归并排序不太了解的我推荐一个博客,里面有很详细的图解;链接:http://www.cnblogs.com/jillzhang/archive/2007/09/16/894936.html
#include<iostream> #include<string> #include<cstdio> #include<cstring> #include<queue> #include<map> #include<cmath> #include<stack> #include<set> #include<vector> #include<algorithm> #define LL long long #define inf 1<<30 #define s(a) scanf("%d",&a) #define Clear(a,b) memset(a,b,sizeof(a)) using namespace std; const int N=200005; int n,ans; int a[N],b[N]; void Merge_Array(int l,int mid,int r) // 二路合并; { int i=l,j=mid+1,k=0; int *p; p=(int *)malloc((r-l+1)*sizeof(int)); while(i<=mid&&j<=r){ if(a[i]<=a[j]){ p[k++]=a[i++]; }else{ p[k++]=a[j++]; ans+=mid-i+1; } } while(i<=mid){ p[k++]=a[i++]; } while(j<=r){ p[k++]=a[j++]; } int cnt=0; for(int i=l;i<=r;i++){ a[i]=p[cnt++]; } free(p); } void Merge_Sort(int l,int r) // 分治法,调用递归; { if(l<r){ int mid=(l+r)>>1; Merge_Sort(l,mid); Merge_Sort(mid+1,r); Merge_Array(l,mid,r); } } int main() { while(~scanf("%d",&n)){ ans=0; for(int i=0;i<n;i++){s(a[i]);b[i]=a[i];} Merge_Sort(0,n-1); // 从0到n-1排序; int cnt=ans; for(int i=0;i<n;i++){ ans=ans-b[i]+n-1-b[i]; if(cnt>ans) cnt=ans; } printf("%d\n",cnt); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-11-06 19:33:25