微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Codeforces Round #189 (Div. 1) C - Kalila and Dimna in the Logging Industry 斜率优化dp

C - Kalila and Dimna in the Logging Industry

很容易能得到状态转移方程 dp[ i ] = min( dp[ j ] + b[ j ] * a[ i ] ), 然后斜率优化一下。

一直以为炸精度了, 忽然发现手贱把while 写成了if 。。。。

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define PLL pair<LL,LL>
#define PLI pair<LL,int>
#define PII pair<int,int>
#define SZ(x) ((int)x.size())
#define ull unsigned long long
using namespace std;

const int N = 4e5 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-8;

int n,que[N],head,rear;
LL a[N],b[N],dp[N];

double calc(int k,int j) {
    return 1.0 * (dp[j] - dp[k]) * (b[k] - b[j]);
}

int main() {
    scanf("%d",&n);
    for(int i = 1; i <= n; i++) scanf("%lld",&a[i]);
    for(int i = 1; i <= n; i++) scanf("%lld",&b[i]);
    dp[1] = 0;
    head = 1,rear = 0;
    que[++rear] = 1;
    for(int i = 2; i <= n; i++) {
        while(rear - head + 1 >= 2 && calc(que[head],que[head + 1]) < a[i]) head++;
        dp[i] = dp[que[head]] + b[que[head]] * a[i];
        while(rear - head + 1 >= 2  && calc(que[rear-1],que[rear]) >= calc(que[rear],i)) rear--;
        que[++rear] = i;
    }
    printf("%lld\n",dp[n]);
    return 0;
}

/*
*/

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。