hdu 1394 Minimum Inversion Number

    技术2022-05-19  20

    这题树状数组挺好做的,只是转化比较巧妙

    可以这样考虑:原来有n个空位,从左到右扫描原序列,扫描到第i个,则a[i]的位置被"占据",

    所有1----a[i]的空位数加起来就是原序列的inversion number,用树状数组解决上述问题。第二个序列由原序列得到,第三个序列由第二个变化得到.........原序列得到第二个序列时,即t-a[1]+1+n-a[i],接下来的就简单了

    #include<iostream> using namespace std; #define N 5005 int c[N],a[N]; int low(int k) { return k&(-k); } void update(int k,int n) { while(k<=n) { c[k]++; k+=low(k); } return ; } int query(int k) { int sum=0; while(k>0) { sum+=c[k]; k-=low(k); } return sum; } int main() { int n,i,minn,t,temp; while(scanf("%d",&n)!=EOF) { for(i=1;i<=n;i++) { scanf("%d",&temp); a[i]=++temp; } memset(c,0,sizeof(c)); t=0; for(i=1;i<=n;i++) { update(a[i],n); t+=(a[i]-query(a[i])); } minn=t; for(i=1;i<n;i++) { if(t+n-2*a[i]+1<minn) minn=t+n-2*a[i]+1; t=t+n-2*a[i]+1; } printf("%d/n",minn); } return 0; }


    最新回复(0)