Codeforces 311B Cats Transport

第一次用斜率优化DP

用双端队列维护前一次的dp值。


代码:

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair<int, int> PII;
const int N = 1e5+5;

ll sum[N]{0}, a[N], dp[N], f[N];
int Q[N];

int main() {
    int n, m, p, h;
    cin >> n >> m >> p;
    for(int i = 1; i < n; i++) { scanf("%lld", &f[i]); sum[i+1] = sum[i]+f[i];}
    for(int i = 1; i <= m; i++) { scanf("%d%lld", &h, &a[i]); a[i] -= sum[h]; }
    sort(a+1, a+m+1);
    for(int i = m; i >= 1; i--) a[i] -= a[1];
    for(int i = 1; i <= m; i++) {
        sum[i] = sum[i-1]+a[i];
        dp[i] = a[i]*i-sum[i];
    }

    for(int j = 1; j < p; j++) {
        for(int i = 1; i <= m; i++) f[i] = dp[i]+sum[i];
        int h = 0, t = -1;
        for(int i = 1; i <= m; i++) {
            while(h<t && (f[Q[h+1]]-f[Q[h]])<a[i]*(Q[h+1]-Q[h])) ++h;
            while(h<t && (f[Q[t]]-f[Q[t-1]])*(i-Q[t])>(f[i]-f[Q[t]])*(Q[t]-Q[t-1])) --t;
            Q[++t] = i;
            dp[i] = f[Q[h]]+a[i]*(i-Q[h])-sum[i];
        }
    }
    printf("%lld\n", dp[m]);
    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值