【bzoj1010】【斜率优化】【HNOI2008】玩具装箱toy

斜率优化DP经典入门题,网上有大量题解
#include<cstdio>
typedef long long LL;
const int maxn=60000;
 
LL s[maxn],f[maxn],g[maxn],h[maxn];
int q[maxn],l,r;
int n,c;
 
inline void count(int i){
    h[i]=f[i]+(g[i]+c)*(g[i]+c);
}   
 
inline bool check(int i){
    if (r-l+1<2) return false;
    int j=q[r-1], k=q[r];
    return (h[i]-h[k])*(g[k]-g[j]) <= (h[k]-h[j])*(g[i]-g[k]);
}
 
inline LL zy(int j, int i){
    return f[j]+(g[i]-g[j]-c)*(g[i]-g[j]-c);
}
     
int main(){
    scanf("%d%d",&n,&c);
    c++;
    for (int i=1;i<=n;i++){
        int t; scanf("%d",&t);
        s[i]=s[i-1]+LL(t);
    }
     
    count(0);
    l=r=1; q[1]=0;
     
    for (int i=1;i<=n;i++){
        g[i]=s[i]+i;
        while (l<r && zy(q[l],i)>=zy(q[l+1],i)) l++;
        f[i]=zy(q[l],i);     
        count(i);
        while (check(i)) r--;
        q[++r]=i;
    }
     
    printf("%lld\n",f[n]);
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值