zoukankan      html  css  js  c++  java
  • POJ3079 K-Anonymous Sequence

    题目链接:POJ3079 K-Anonymous Sequence
    题目大意:

    (T) 组数据,有一个长度为 (N) 的单调不下降的序列 (A) ,每一次操作可以将其中一个数字 (A_i) 减1,要求操作后的序列满足每个数字都存在至少 (k-1) 个元素和其大小相等,求操作数的最小值。
    (Tleq 20,2leq Nleq 500000)(forall A_iin [0,500000])

    思路:
    (dp[i]) 为对于前 (i) 个数的最小值,(sum[i]=sum_{j=1}^i{a_i}),显然将连续的一段 (A_i) 变为同一个值是较优的,首先可以得到 (O(n^2)) 的朴素DP:

    [dp[i]=min_{0leq jleq i-k}{dp[j]+sum[i]-sum[j]-(i-j)*a[j+1]} ]

    考虑优化,将与 (j) 无关的项移到外面,简单整理:

    [dp[i]=min_{0leq j<i}{dp[j]-sum[j]+j*a[j+1]-i*a[j+1]}+sum[i] ]

    这里有 (i*a[j+1]) 的乘积式,可以斜率优化,将min去掉,移项后可以得到:

    [dp[j]+j*a[j+1]-sum[j]=i*a[j+1]+dp[i]-sum[i] ]

    (dp[j]+j*a[j+1]-sum[j]) 作为纵坐标, (a[j+1]) 作为横坐标,由于后者和斜率 (i) 都是单调递增的,可以用单调队列直接维护凸壳,时间复杂度 (O(n))

    实现细节:

    • 这个数据范围显然要开long long。
    • 等到 (dp[i]) 要进行转移时再将 (i-k) 加入单调队列,否则本身要转移的最优状态可能会被后面加入但暂时不转移的状态淘汰掉。
    • (2k)(dp) 没有转移状态,应直接计算整体成块的答案。

    Code:

    #include<iostream>
    #include<cstdio>
    #define N 500100
    #define ll long long
    using namespace std;
    inline int read(){
        int s=0,w=1;
        char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9')s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
        return s*w;
    }
    ll a[N],dp[N],sum[N],q[N];
    int T,n,k,l,r;
    ll dx(ll i,ll j){
        return a[i+1]-a[j+1];
    }
    ll dy(ll i,ll j){
        return (dp[i]+i*a[i+1]-sum[i])-(dp[j]+j*a[j+1]-sum[j]);
    }
    int main(){
        T=read();
        while(T--){
            n=read(),k=read();
            for(int i=0;i<n;i++)
                sum[i+1]=sum[i]+(a[i+1]=read());
            l=0,r=-1;
            for(int i=1;i<=n;i++){
                if(i<2*k){dp[i]=dp[i-1]+a[i]-a[1];continue;}
                while(l<r&&dy(q[r],q[r-1])*dx(i-k,q[r])>=dy(i-k,q[r])*dx(q[r],q[r-1]))r--;
                q[++r]=i-k;
                while(l<r&&dy(q[l+1],q[l])<=dx(q[l+1],q[l])*i)l++;
                dp[i]=dp[q[l]]+sum[i]-sum[q[l]]-(i-q[l])*a[q[l]+1];
            }
            printf("%lld
    ",dp[n]);
        }
        return 0;
    }
    
  • 相关阅读:
    OpenCv 学习安装(一)
    mysql 5.7.22安装
    sql游标
    (转)C# 获取当前路径的7中方法
    IIS 配置好了,为什么网站打开一片空白?
    (转)C#文件操作
    关于电脑开机不出现桌面即不启动explorer.exe桌面程序--------正解
    C#中 非静态字段、方法或属性“XXXX”要求对象引用-----解决方案
    关于svn获取获取文件时 Unable to connect to a repository at URL"https://..."执行上下文错误:参数错误
    获取汉字全拼、首字母缩写
  • 原文地址:https://www.cnblogs.com/Neal-lee/p/14070846.html
Copyright © 2011-2022 走看看