dp 斜率优化

关键词:dp,斜率优化
dp[i]=min/max{dp[j]+fun(i,j),1<=j< i},当i和j可分离时,用单调队列维护即可(维护前j个中的最小/大值);当i和j不可分离时,可使用斜率优化。
1.设k< j,通过假设j点比k点更优,可推出g(j,k)< f(i)的形式,将j,k与i分离开来
2.若k< j< i,且g(j,k)>g(i,j),则j一定不能取得最优解。
证明:若g(i,j) < f(i),则i点比j点更优,j点不能取得最优解;若g(i,j)>f(i),则g(j,k)>g(i,j)>f(i),k比j更优,j也不能取得最优解。综上,j不能取得最优解
如图所示:

这里写图片描述

综合以上分析,可用单调队列维护dp[i]:
1,用一个单调队列来维护解集。
2,假设队列中从头到尾已经有元素a b c。那么当d要入队的时候,我们维护队列的上凸性质,即如果g[d,c] < g[c,b],那么就将c点删除。直到找到g[d,x]>=g[x,y]为止,并将d点加入在该位置中。
3,求解时候,从队头开始,如果已有元素a b c,当i点要求解时,如果g[b,a] < sum[i],那么说明b点比a点更优,a点可以排除,于是a出队。最后dp[i]=getDp(q[head])。
斜率优化模板:

head=0,tail=-1;
que[++tail]=0,dp[0]=0;//初始化可能有所不同
for(int i=1;i<=n;i++){
    while(head+1<=tail&&getup(que[head+1],que[head])<f[i]*getdown(que[head+1],que[head])) head++;
    int t=que[head];
    dp[i]=getdp(i,t);
    while(head+1<=tail&&getup(i,que[tail])*getdown(que[tail],que[tail-1])<getup(que[tail],que[tail-1])*getdown(i,que[tail])) tail--;
    que[++tail]=i;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值