BZOJ1010

1010: [HNOI2008]玩具装箱toy

思路:斜率优化

Fi 为前 i 个玩具的最优答案
递推式:Fi=Min{ Fj+(ij1+sumisumjL)2 }

斜率优化的思想咯:若j比k优,则有
Fj+(ij1+sumisumjL)2<Fk+(ik1+sumisumkL)2
基本数学知识可以化成:
[Fk+(sumk+k+L+1)2][Fj+(sumj+j+L+1)2]>2(sumk+ksumjj)(sumi+i)

sumi i <script id="MathJax-Element-270" type="math/tex">i</script>都是单调递增的,除过去用朴素的斜率优化就好

代码:

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN=50010;
typedef long long ull;
int n,L;
ull c[MAXN];
ull sum[MAXN];
ull f[MAXN];
int stack[MAXN];
int l,r;
ull a(int i) { return sum[i]+i; }
ull x(int i) { return 2*a(i); }
ull y(int i) { return f[i]+(a(i)+L+1)*(a(i)+L+1); }
void init()
{
    cin>>n>>L;
    for (int i=1;i<=n;i++) {
        scanf("%I64d",&c[i]);
        sum[i]=sum[i-1]+c[i]; }
    l=r=0;
    for (int i=1;i<=n;i++) {
        while (l<r && (y(stack[l+1])-y(stack[l]))<=a(i)*(x(stack[l+1])-x(stack[l])))
            stack[l++]=0;
        f[i]=f[stack[l]]+(i-stack[l]-1+sum[i]-sum[stack[l]]-L)*(i-stack[l]-1+sum[i]-sum[stack[l]]-L);
        while (l<=r && (y(i)-y(stack[r-1]))*(x(i)-x(stack[r]))>(y(i)-y(stack[r]))*(x(i)-x(stack[r-1])))
            stack[r--]=0;
        stack[++r]=i; }
    cout<<f[n]<<endl;
    return ;
}
int main()
{
    init();
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值