ICode9

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

题解 P7594 【Clear Up】(贪心,模拟)

2022-02-09 16:35:52  阅读:144  来源: 互联网

标签:直线 题解 Clear Up ret st b1 b2 top


考场降智,对于带 0 的数据打了一个不知道是什么鬼东西的算法,还调挂了(


对于这些方块,我们把它们看成是 \(n\) 个平面上的点 \((i,a_i)\),那么样例 \(1\) 就长这样:

样例 \(2\) 就长这样:

我们发现就可以转换为这样一个问题:找到若干对直线 \(y1_i= x +b1_i\) 和 \(y2_i=-x +b2_i\),并使得 \(\sum (b1_i+b2_i)\) 最小(即截距之和最小),最后答案就是:
\(\sum \lceil\frac{(b1_i+b2_i)}{2}\rceil\) 。

长得有点像线性规划?(考场上就一直往线性规划上想,最后只有 45 pts),但其实没有那么复杂。

考虑这样一个结论:两对直线 \(y1_a,y2_a\) 和 \(y1_b,y2_b\) ,其中第一对直线交点 \(x_1\) 小于第二对直线交点 \(x_2\),若 \(y2_a\) 与 \(y1_b\) 的交点的 \(y\) 坐标 \(\geq 0\),则这两对直线可以合并成一对直线 \(y1_c=x+max(y1_a,y1_b),y2_c=-x+max(y2_a,y2_b)\)。

为什么?来感性理解一下,看这张图:

如图,两对黑色的直线(这里为了好看,画成射线)是原本的两队直线,红色(\(HR\) 和 \(HT\))的是合并后的一对直线,我们发现,这样的一对橙色线可以完美盖住两对黑色线的部分,还多盖住了标出的矩形的位置;并且,我们多画几个就会发现总是满足:\(\frac{b1_c+b2_c}{2}\leq \frac{b1_a+b2_a}{2}+\frac{b1_b+b2_b}{2}\),极限情况是交点在 \(x\) 轴上,此时 \(\frac{b1_c+b2_c}{2}= \frac{b1_a+b2_a}{2}+\frac{b1_b+b2_b}{2}\)。

那么只有有两对这样满足条件的直线,合并就一定更优。


具体做法有很多中,这里提供一个简单的做法:

我们发现可合并的直线对一定是相邻的,那么就可以这样:首先开一个栈记录从前向后的直线对。对于每个点,我们把它单独视为一个区间,两条直线分别为:\(y1_i=x+a_i-i\) 和 \(y2_i=-x+a_i+i\)。每新加入一个区间(点),从栈顶向下一直与可合并的区间合并,然后将合并完的新区间放到栈顶。最后扫一遍栈统计答案就行了。

代码:

#include<bits/stdc++.h>
using namespace std;
#define rg register
#define inf 0x3f3f3f3f3f3f3f3f
#define ll long long
inline int read(){
	rg int ret=0,f=0;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=1;ch=getchar();}
    while(isdigit(ch)){ret=ret*10+ch-48;ch=getchar();}
    return f?-ret:ret;
}
struct node{
	ll b1,b2;
}st[1000005],now;  //开栈。 
int n,top;
ll a[1000005],ans;  
inline node merge(node a,node b){
	node ret;
	ret.b1=max(a.b1,b.b1); ret.b2=max(b.b2,a.b2);
	return ret;
} //合并直线(区间)。 
signed main(){
	n=read();
	for(rg int i=1;i<=n;++i){
		a[i]=read(); now.b1=a[i]-i; now.b2=a[i]+i;  //将新加入的点视为一个已处理好的区间。 
		while(((st[top].b2+now.b1)>>1>=0)&&top) 
			now=merge(st[top--],now);   //不断 merge 并 pop。 
		st[++top]=now;    
	}
	while(top){
		if((st[top].b2+st[top].b1)&1) ans+=(st[top].b2+st[top].b1+1)>>1;
		else ans+=(st[top].b2+st[top].b1)>>1;
		--top;
	} //统计答案。 
	printf("%lld",ans);
	return 0;
}

标签:直线,题解,Clear,Up,ret,st,b1,b2,top
来源: https://www.cnblogs.com/tiatto/p/15875611.html

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

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

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

ICode9版权所有