hdoj1394
题目大意:刚开始看错了题目,以为求出逆序数就行了,就是求不出样例的值,有看原来是求出一系列的逆序数序列的最小数
解决:树状数组
#include <iostream> #include <cstdio> using namespace std; #define LL __int64 const int N=5000; int n; int num[N+5]; int c[N+5]; inline int lowbit(int x) { return x&(-x); } void update(int p,int delta) { for(int i=p;i<=n;i+=lowbit(i)) c[i]+=delta; } int getsum(int p) { int sum=0; for(int i=p;i>0;i-=lowbit(i)) sum+=c[i]; return sum; } int main() { int t; while(scanf("%d",&n)!=EOF) { LL cnt=0; int tmp; for(int i=1;i<=n;i++) { scanf("%d",&t); num[i]=t; //统计出前边比该数小的数,在用前边的数的个数i-1减去比该数小的 //就是比该数大的,即逆序数 cnt+=(i-1-getsum(t)); update(t+1,1); } LL res=cnt; for(int i=1;i<n;i++) {/*第一个数移到最后一位,第一个数前边没有比该数大的 即第一个数在最前边的逆序是0,移动到最后边的时候 前边的数的个数是n-num[i],比该数大的数即增加的逆序数的 个数是再减去该数本身和前边的数比如3,减去0,1,2,3四个数*/ res=res+ n-num[i]-(num[i]+1); if(res < cnt)cnt=res; } printf("%I64d\n",cnt); memset(c,0,sizeof(c)); } system("pause"); return 0; }