当前位置: 移动技术网 > IT编程>开发语言>C/C++ > 带权二分口胡

带权二分口胡

2019年06月04日  | 移动技术网IT编程  | 我要评论

因为爱情有晴天98集,只要为你活一天伴奏,家装大全

例题

长度为n的正整数序列分为m段,求每段和的方差乘以m^2的最小值。——《sdoi2016 征途》

例题-solve(fake)

设分为\(m\)段每段长度为\(x_i\),此时的答案为
\[ m^2\frac{\sum_i(x_i-\bar x)^2}{m}=m\sum_ix_i^2-2m\bar x\sum_ix_i+m^2\bar x^2=m\sum_ix_i^2-(\sum_ix_i)^2 \]
所以实际上是要最小化每段的平方和。然后可以写暴力了,得出一个\(o(n^2m)\)的优秀算法。

带权二分

或称斜率凸优化、wqs二分,用于解决总共恰好有k次决策的最优化问题,设g(x)恰好x次的答案,g(x)呈现凸性(g'(x)单增或单减)。

简单理解“带权二分“,所谓“带权”就是对决策附加一个代价-c,然后计算没有次数限制的最优解g及取到最优解所需的最少决策次数t(这一问题需要能快速求解),所谓”二分“则是通过二分所带权值使t等于所要求的k。

不太直观?我们考虑凸函数g(x)与y=cx+b相切时的切点横坐标x0,这实际上是函数g(x)-cx的最大值(最小值)点的横坐标。也能从导数方面解释:切点处g'(x0)=c,而g'(x)单调,故(g(x)-cx)'=g'(x)-c存在零点x0。所以带权c有即二分切线斜率,此时的最优解所需决策次数t正是切点的横坐标x0。

这样,我们就在函数图像方面认识了这一过程。

再谈二分

斜率/权值c的范围是什么?实际上c的范围只要能包含所有的g(x+1)-g(x)/1就行了。当如果g(x+1)-g(x)/1是全是整数时,我们甚至可以在整数域二分。

而实际上每次球的时最少决策次数,这可能永远不会等于k,实际答案为g+mc而非g+tc。

凸性的判定

大概题目的凸性都不太好证明吧。因此可以采用打表法意会法,例如例题中,显然g(x)比g(x+1)是不优的(因为\((a+b)^2>a^2+b^2\))并且g(x)比g(x+1)不优的程度因大于g(x+1)比g(x+2)不优的程度,推广开就可以认为g(x)是有凸性的了。

例题-solve

整数域上二分权值c,设f[i]表示前i个分为若干段的最小平方和,显然有f[0]=0,f[i]=f[j]+(s[i]-s[j])^2+c。而这是一个斜率优化可以解决的;设g[i]表示产生f[i]的最小决策次数,显然g[i]单调不降。这意味着转移i时如存在j1,j2都能取到较优解时,因考虑从g[j1]处更新g[i]。

#include <bits/stdc++.h>
#define ll long long 
using namespace std;
const int n=3e3+10;

int n,m,q[n];
ll s[n],f[n],g[n];

inline double slope(int x,int y) {
    return (double)(f[y]+s[y]*s[y]-f[x]-s[x]*s[x])/(s[y]-s[x]);
}
inline void check(int c) {
    static int h,t;
    q[h=t=0]=f[0]=g[0]=0;
    for(int i=1; i<=n; ++i) {
        while(h<t&&slope(q[h],q[h+1])<2*s[i]) ++h;
        f[i]=f[q[h]]-c+(s[i]-s[q[h]])*(s[i]-s[q[h]]);
        g[i]=g[q[h]]+1;
        while(h<t&&slope(q[t-1],q[t])>slope(q[t],i)) --t;
        q[++t]=i;
    }
}

int main() {
    scanf("%d%d",&n,&m);
    for(int i=1; i<=n; ++i) {
        scanf("%lld",s+i);
        s[i]+=s[i-1];
    }
    int l=-s[n]*s[n],r=0,mid,c=0;
    while(l<=r) {
        mid=l+(r-l)/2; check(mid);
        if(g[n]<=m) l=mid+1,c=mid;
        else r=mid-1;
    }
    check(c);
    printf("%lld\n",(f[n]+m*c)*m-s[n]*s[n]);
    return 0;
}

事实上,带权二分还能做一些非dp的最优化问题,例如 bzoj2654,基本方法始终是不变的。

没想到吧,这竟然还是一篇讲义 2333。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网