您的位置:首页 > 其它

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

2017-09-06 17:08 381 查看

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
[k],而应该是f[k+1][k]到f
[k]的最大值

代码

#include <bits/stdc++.h>

#define K 105
#define N 20050
#define ll long long

int 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
;

ll Q
;
int head,tail;

ll sum
;

ll f
[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);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: