• $CH0601 Genius ACM$ 倍增优化DP


    ACWing

    Description

     给定一个长度为N的数列A以及一个整数T.我们要把A分成若干段,使得每一段的'校验值'都不超过N.求最少需要分成几段.

    Sol

    首先是校验值的求法:

    要使得'每对数的差的平方'之和最大,显然就是先排序,然后取最大和最小为一对,次大和次小为一对.....

    然后是问题的转化:求最少分的段数,显然就是确定左端点后,在校验值不超过T的前提下尽量扩展右端点.

    优化就在于右端点的扩展,当然就是用倍增辣qwq

    还有就是求校验值的优化:可以不用每次都快排,而是先排增加的一段,然后归并就好了

    Code

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #define il inline
    #define Rg register
    #define go(i,a,b) for(Rg int i=a;i<=b;i++)
    #define yes(i,a,b) for(Rg int i=a;i>=b;i++)
    #define ll long long
    using namespace std;
    il int read()
    {
        int x=0,y=1;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
        return x*y;
    }
    int T,n,m,as,a[500001],b[500001],c[500001];
    ll K;
    il bool ck(int l,int r,int md)
    {
        go(i,md,r)b[i]=a[i];
        sort(b+md,b+r+1);
        int i=l,j=md;
        go(k,l,r)
            if((i<=md-1 && b[i]<b[j]) || j>r)c[k]=b[i++];
            else c[k]=b[j++];
        i=l,j=r;int t=min(m,(r-l+1)/2);ll nw=0;
        while(t--)
            nw+=1LL*(c[i]-c[j])*(c[i]-c[j]),i++,j--;
        if(nw<=K)
        {
            go(i,l,r)b[i]=c[i];
            return 1;
        }
        return 0;
    }
    int main()
    {
        T=read();
        while(T--)
        {
            n=read(),m=read();scanf("%lld",&K);as=0;
            go(i,1,n)a[i]=read();
            int l=1,r=1,p=1;
            b[1]=a[1];
            while(l<=n)
            {
                if(r+p<=n && ck(l,r+p,r+1))r+=p,p*=2;
                else p/=2;
                if(!p || r==n){as++,l=++r,p=1,b[l]=a[l];}
            }
            printf("%d
    ",as);
        }
        return 0;
    }
    View Code
    光伴随的阴影
  • 相关阅读:
    Caffe + Ubuntu 15.04 + CUDA 7.0 新手安装配置指南
    姚斌分布式作业一
    一个简单正则表达式引擎的实现
    学习编程的方法
    [Leetcode]012. Integer to Roman
    [Leetcode]011. Container With Most Water
    JOS lab1 part2 分析
    我的Android Studio配置
    [Leetcode]009.Palindrome Number
    [Leetcode]008.String to Integer (atoi)
  • 原文地址:https://www.cnblogs.com/forward777/p/11240241.html
Copyright © 2020-2023  润新知