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

这篇博客介绍了NOIP2017提高组模拟赛中的一道题目——遥远的金字塔,重点讨论了如何通过动态规划(DP)和斜率优化来解决这个问题。给出了数据约束、样例输入输出,并提供了题解和代码实现。

【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);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值