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

Input

Output

Sample Input
5 3
1 6
1 5
3 5
4 4
4 4
Sample Output
15
Data Constraint

Hint

题解
显然是DP
设f[i][j]表示选择了j个矩形,最后一个顶部在i层的最大覆盖面积
则转移有 
可以想到斜率优化

code
#include<cstdio>
#include<cctype>
#include<cstdlib>
#include<cstring>
#define R register
#define max(a,b) (a>b?a:b)
using namespace std;
const int N=20100,M=105;
int n,m,d[M][N],h[M],t[M];
long long f[N][M],a[N],ans;
inline void read(R long long &x){
x=0;char ch=getchar();
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
}
long double s(int i,int j,int k){return 1.0*(f[j][i]-f[k][i])/(j-k);}
int main(){
scanf("%d%d",&n,&m);
long long x,y;
for(int i=1;i<=n;++i)read(x),read(y),a[i]=y-x+1,h[i]=1;
memset(f,0,sizeof f);
for(int i=1;i<=n;++i){
f[i][1]=a[i]*i;
for(int j=1;j<=m;++j){
while(h[j-1]<t[j-1]&&s(j-1,d[j-1][h[j-1]+1],d[j-1][h[j-1]])>1.0*a[i])++h[j-1];
f[i][j]=f[d[j-1][h[j-1]]][j-1]+a[i]*(i-d[j-1][h[j-1]]);
while(h[j]<t[j]&&s(j,d[j][t[j]],d[j][t[j]-1])<s(j,i,d[j][t[j]]))--t[j];
d[j][++t[j]]=i;
}
ans=max(ans,f[i][m]);
}
printf("%lld",ans);
}
这篇博客介绍了NOIP2017提高组模拟赛中的一道题目——遥远的金字塔,重点讨论了如何通过动态规划(DP)和斜率优化来解决这个问题。给出了数据约束、样例输入输出,并提供了题解和代码实现。

443

被折叠的 条评论
为什么被折叠?



