zoukankan      html  css  js  c++  java
  • Minimum Inversion Number(最小翻转次数)

    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;
    }
    

  • 相关阅读:
    记账本开发进程第四天
    记账本开发进程第三天
    记账本开发进程第二天
    记账本开发进程第一天
    《人月神话》阅读笔记三
    《人月神话》阅读笔记二
    一、计算机基础
    Fox and Minimal path CodeForces
    Maximum Value (二分+思维枚举)
    True Liars (思维想法+带权并并查集+01背包)
  • 原文地址:https://www.cnblogs.com/hpustudent/p/2193459.html
Copyright © 2011-2022 走看看