• BZOJ4240: 有趣的家庭菜园


    【传送门:BZOJ4240


    简要题意:

      给出一个长度为n的序列,可以将相邻的数交换位置,要求通过最少交换次数使得这个序列呈左边段不递减,右边段不递增


    题解:

      树状数组+贪心

      将每个数一开始的下标为原本的位置,最后得到的序列的逆序对数就是操作的次数

      首先得到的序列肯定是最大的在中间,第二大的在旁边。。

      那么就贪心放值,放的时候找左右两边能产生逆序对最少的放就可以了,用树状数组维护逆序对数

      注意一下多个值相等的情况,且要加long long


    参考代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<cstdlib>
    using namespace std;
    typedef long long LL;
    int a[310000];
    int lowbit(int x){return x&-x;}
    int n;
    void change(int x,int d)
    {
        while(x<=n)
        {
            a[x]+=d;
            x+=lowbit(x);
        }
    }
    int getsum(int x)
    {
        int ans=0;
        while(x!=0)
        {
            ans+=a[x];
            x-=lowbit(x);
        }
        return ans;
    }
    struct node
    {
        int id,d;
    }h[310000];
    bool cmp(node n1,node n2)
    {
        return n1.d>n2.d;
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&h[i].d);
            h[i].id=i;
        }
        sort(h+1,h+n+1,cmp);
        LL ans=0;
        for(int i=1;i<=n;)
        {
            int j=i-1;
            do
            {
                j++;
                int sum=getsum(h[j].id);
                ans+=min(sum,i-1-sum);
            }while(h[j+1].d==h[j].d);
            for(;i<=j;i++) change(h[i].id,1);
        }
        printf("%lld
    ",ans);
        return 0;
    }

     

  • 相关阅读:
    6种负载均衡算法
    Java中volatile关键字
    剑指offer练习
    linux系统查看IP地址,不显示IP地址或者只显示127.0.0.1
    Nginx负载均衡配置
    集群应用Session一致性实现的三种方案
    rabbitMQ学习
    JDK1.8在LINUX下安装步骤
    ecplise部署gradle web项目
    Kubernetes下的应用监控解决方案
  • 原文地址:https://www.cnblogs.com/Never-mind/p/8881228.html
Copyright © 2020-2023  润新知