JZOJ 5347. 【NOIP2017提高A组模拟9.5】遥远的金字塔

来源:互联网 发布:陕西seo服务 编辑:程序博客网 时间:2024/05/16 00:27

Description

这里写图片描述

分析

其实这就是很明显的一道斜率优化的dp式子,我们首先可以得到最显然的dp方程,设f[i][j]表示前i层数分成j个不相交的矩形的最大面积,那么我们有:

f[i][j]=max(f[i-k+1][j-1]+(y[i]-x[i])*k),k为与当前这一块联通的矩形宽。

很明显,这个式子等价于f[i][k]=max(f[j][k-1]+(y[i]-x[i])*(i-j)),然后就可以斜率优化了

有一个小细节,我就是这里错了然后就很愉快爆炸了,最终的答案显然不应该是f[n][k],而应该是f[k+1][k]到f[n][k]的最大值

代码

#include <bits/stdc++.h>#define K 105#define N 20050#define ll long longint read(){    int x = 0, f = 1;    char ch = getchar();    while (ch < '0' || ch > '9') {if (ch == '-') f = -1; ch = getchar();}    while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}    return x * f;}struct NOTE{    ll x,y;}a[N];ll Q[N];int head,tail;ll sum[N];ll f[N][K];int main(){    freopen("pyramid.in","r",stdin);    freopen("pyramid.out","w",stdout);    int n = read(), k = read();    for (int i = 1; i <= n; i++)        a[i].x = read(), a[i].y = read(), sum[i] = a[i].y - a[i].x + 1;    for (int j = 1; j <= k; j++)    {        head = 1, tail = 1;        Q[head] = 0;        for (int i = 1; i <= n; i++)        {            while (head < tail && sum[i] * (Q[head] - Q[head + 1]) >= f[Q[head]][j - 1] - f[Q[head + 1]][j - 1])                head++;            f[i][j] = f[Q[head]][j - 1] + sum[i] * i - sum[i] * Q[head];            while (head < tail && (f[Q[tail - 1]][j - 1] - f[Q[tail]][j - 1]) * (Q[tail] - i) <= (f[Q[tail]][j - 1] - f[i][j - 1]) * (Q[tail - 1] - Q[tail]))                tail--;            Q[++tail] = i;        }    }    ll ans = 0;    for (int i = k + 1; i <= n; i++)        ans = std::max(f[i][k], ans);    printf("%lld\n",ans);}
阅读全文
0 0
原创粉丝点击