斜率优化 dp 抱铃求助
查看原帖
斜率优化 dp 抱铃求助
610557
shinzanmonoszm 妹妹楼主2023/6/3 13:03
#include<iostream>
#include<algorithm>
#include<limits>
#include<queue>
const int sz=5e4+10;
using ll=long long;
struct piit{
    ll x,y;
    piit operator-(const piit&a)const{
        return piit{x-a.x,y-a.y};
    }
};
const ll inf=std::numeric_limits<ll>::max()/2;
ll s[sz],f[sz];
piit pts[sz],qq[sz];
bool inq(piit a,piit b,piit c){
    ll dxab=(a-b).x,dyab=(a-b).y,dxbc=(b-c).x,dybc=(b-c).y;
    return dyab*dxbc<dybc*dxab;
}
int main(){
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    int n,l;
    std::cin>>n>>l,l++;
    for(int i=1;i<=n;i++)
        std::cin>>s[i],s[i]+=s[i-1]+1;
    int head=1,tail=1;
    for(int i=1;i<=n;i++){
        ll k=-2*(s[i]-l);
        while(head<tail&&1.*(qq[head]-qq[head+1]).y/(qq[head]-qq[head+1]).x<k)head++;
        ll x=qq[head].x,y=qq[head].y;
        f[i]=std::min(y-k*x,0ll)+(s[i]-l)*(s[i]-l);
        piit p=piit{s[i],s[i]*s[i]-f[i]};
        while(head<tail&&!inq(qq[tail-1],qq[tail],p))tail--;
        qq[++tail]=p;
    }
    std::cout<<f[n];
    return 0;
}
2023/6/3 13:03
加载中...