ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

bzoj2650. 积木

2022-06-24 09:03:06  阅读:145  来源: 互联网

标签:bzoj2650 ch min int top 积木 mathcal include


传送门

一眼看上去不太可做,先找结论。

本题的核心思路:如果一个位置一边比它大,一边比它小,且确定了两边不动,那么提升它混乱值没有减小。

重点在于两边都不动,所以考虑 \(i,j\) 是不动的,中间都是动的,发掘一下性质。

首先 \(\min(h_i,h_j)>\max_{k=j+1}^{i-1}h_k\),因为中间如果有大于等于 \(\min(h_i,h_j)\) 的,它们不提升肯定比提升优。

既然中间的要小于两边的,那么它们提升之后肯定也不会超过两边。有了这个,可以推出中间的在提升之后一定变为同一个值。proof:因为左右两边是最大,所以中间在全部变为同一值前肯定存在一个结构:\(h_{k-1}\le h_k< h_{k+1}\),且 \(h_k\) 至少提升 \(1\),但是如果 \(h_{k-1}\) 不跟上混乱值不会减小,所以 \(h_{k-1}\) 必须跟上。重复以上步骤,最终中间会变为同一个值。

设中间最后变成的值为 \(x\),显然 \(\min(h_i,h_j)\ge x\ge \max_{k=j+1}^{i-1}h_k\)。\(x\) 取什么最优就是一个二次函数求最值,可以 \(\mathcal{O}(1)\) 完成。

考虑 DP,\(f_i\) 表示考虑了前 \(i\) 个,第 \(i\) 个值不动的答案,显然可以枚举 \(j\) 转移,时间 \(\mathcal{O}(n^2)\),但是有限制条件 \(\min(h_i,h_j)>\max_{k=j+1}^{i-1}h_k\),根据某场 ZR 模拟赛,这样的碗装结构只有 \(\mathcal{O}(n)\) 个(其实就差不多是单调栈出栈次数),可以用单调栈找出,时间复杂度 \(\mathcal{O}(n)\)。

对于统计答案,我们可以在开头结尾加一个 INF,且它们不参与混乱值的计算,以上结论分析一下还是对的。

#include<iostream>
#include<stdio.h>
#include<ctype.h>
#include<math.h>
#define int long long
#define N 1000005
using namespace std;
inline int read(){
	int x=0,f=0; char ch=getchar();
	while(!isdigit(ch)) f|=(ch==45),ch=getchar();
	while(isdigit(ch)) x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
	return f?-x:x;
}
int n,c,h[N],s[N],ss[N],f[N],st[N],top;
inline int calc(int i,int j,int l,int r){
	int A=i-j-1;
	int B=-2*(s[i-1]-s[j])-(i==n+1?0:c)-(j==0?0:c);
	int C=(ss[i-1]-ss[j])+c*((i==n+1?0:h[i])+(j==0?0:h[j]));
	int p=round(-(double)B/double(2*A)),x;
	if(l<=p && p<=r) x=p;
	else if(p<l) x=l;
	else x=r;
	return A*x*x+B*x+C;
}
signed main(){
	n=read(),c=read();
	h[0]=h[n+1]=N;
	for(int i=1;i<=n;++i){
		h[i]=read();
		s[i]=h[i]+s[i-1];
		ss[i]=h[i]*h[i]+ss[i-1];
	}
	st[++top]=0;
	for(int i=1;i<=n+1;++i){
		if(2<=i && i<=n) f[i]=f[i-1]+c*abs(h[i]-h[i-1]);
		else f[i]=f[i-1];
		while(top && h[i]>=h[st[top]]){
			top--;
			if(top){
				int j=st[top],k=st[top+1];
				f[i]=min(f[i],f[j]+calc(i,j,h[k],min(h[i],h[j])));
			}
		}
		st[++top]=i;
	}
	cout<<f[n+1];
	return 0;
}

标签:bzoj2650,ch,min,int,top,积木,mathcal,include
来源: https://www.cnblogs.com/xzzduang/p/16407498.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有