首页 > 其他分享 >AT_joisc2017_c 手持ち花火

AT_joisc2017_c 手持ち花火

时间:2024-08-21 21:28:13浏览次数:6  
标签:va 手持 joisc2017 int sum vb else cost 花火

AT_joisc2017_c 手持ち花火

一道神秘贪心题。

首先显然是二分速度 \(v\)。

然后发现题意可以被理解成其他人逐渐向 \(k\) 靠近,所以若跑了区间 \([l,r]\) ,那么跑的距离就是 \(x_r - x_l\) ,所以就要尽量增长跑动的时间,而注意到题意不是一碰到就要点燃,所以可以跟着跑,也就是说时间就是 \(T*(r-l+1)\)。

然后就转换成了一开始在区间 \([k,k]\),要扩展到 \([1,n]\),若要扩展(距离差为 \(S\))就要先消耗 $ \frac{S} {2v} $ 的代价,再加上 \(T\) 的代价。

这个怎么做呢?我们发现最优方案一定是每次选择一段区间使得要消耗的代价 \(need\) 小于已有的代价,且最终可以使得代价不降。我们发现这个 \(need\) 是单调递增的,所以我们尽量选较小的区间进行扩展。

但是这样仍然有可能最后会有一段无法再进行扩展的区间。假设现在扩展到 \([L,R]\),这个时候就考虑 时光倒流,让区间 \([1,n]\) 尝试缩减到现在扩展的区间 \([L,R]\),因为这样是从最后还有的时间 $ n \times T - \frac{x_n - x_1} {2v} $,反过来考虑,然后就做完了。

点击查看代码
#include<bits/stdc++.h>
#define fir first
#define sec second
#define int long long
#define double long double
#define mkp(a,b) make_pair(a,b)
using namespace std;
typedef pair<int,int> pir; 
inline int read(){
	int x=0,f=1; char c=getchar();
	while(!isdigit(c)){if(c=='-') f=-1; c=getchar();}
	while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48); c=getchar();}
	return x*f;
}
const int mod=998244353,inf=1e9,N=1e5+5;
int n,k,fl;
double a[N],b[N],T,x[N];
int m1,m2;
inline int expand(double *a,int len,int x,double& cost,double& need){
	cost=need=0;
	for(int i=x;i<=len;i++){
		need=max(need,a[i]-cost);
		cost+=T-a[i];
		if(cost>=0) return i;
	}
	return len+1;
}
inline int expand2(double *a,int len,int x,double& cost,double& need){
	cost=need=0;
	for(int i=x;i<=len;i++){
		need=max(need,T-cost);// a_i - (cost - (T - a_i)) = T - cost
		cost+=a[i]-T;
		if(cost>=0) return i;
	}
	return len+1;
}
inline bool chk(int v){
	m1=m2=0;
	for(int i=k-1;i>=1;i--) a[++m1]=(double)(x[i+1]-x[i])/v/2;
	for(int i=k+1;i<=n;i++) b[++m2]=(double)(x[i]-x[i-1])/v/2;
	int nowa=1,nowb=1,las=0,va=1,vb=1;
	double cost_a,cost_b,need_a,need_b,sum=T;
	while(nowa<=m1||nowb<=m2){
		if((las==1||!las)&&nowa<=m1) va=expand(a,m1,nowa,cost_a,need_a);
		if((las==2||!las)&&nowb<=m2) vb=expand(b,m2,nowb,cost_b,need_b);
		int fl_a=(va<=m1&&need_a<=sum),fl_b=(vb<=m2&&need_b<=sum);
		if(fl_a&&fl_b){
			if(cost_a>=cost_b) sum+=cost_a,va=nowa=va+1,las=1;
			else sum+=cost_b,vb=nowb=vb+1,las=2;
		}
		else if(fl_a) sum+=cost_a,va=nowa=va+1,las=1;
		else if(fl_b) sum+=cost_b,vb=nowb=vb+1,las=2;
		else if(va<=m1||vb<=m2) return 0;
		else break;
	}
	reverse(a+1,a+m1+1); reverse(b+1,b+m2+1);
	las=0,m1=m1-nowa+1,m2=m2-nowb+1;
	nowa=1,nowb=1,sum=(double)n*T-(x[n]-x[1])/v/2;
	va=vb=1;
	while(nowa<=m1||nowb<=m2){
		if((las==1||!las)&&nowa<=m1) va=expand2(a,m1,nowa,cost_a,need_a);
		if((las==2||!las)&&nowb<=m2) vb=expand2(b,m2,nowb,cost_b,need_b);
		int fl_a=(va<=m1&&need_a<=sum),fl_b=(vb<=m2&&need_b<=sum);
		if(fl_a&&fl_b){
			if(cost_a>=cost_b) sum+=cost_a,va=nowa=va+1,las=1;
			else sum+=cost_b,vb=nowb=vb+1,las=2;
		}
		else if(fl_a) sum+=cost_a,va=nowa=va+1,las=1;
		else if(fl_b) sum+=cost_b,vb=nowb=vb+1,las=2;
		else return 0;
		
	}
	return 1;
}
signed main(){
//	freopen("in.in","r",stdin);
//	freopen("sparklers.out","w",stdout);
	n=read(),k=read(),T=read();
	for(int i=1;i<=n;i++) x[i]=read();
	if(x[n]==0){puts("0"); return 0;}
//	cout<<chk(101)<<'\n';
	int l=1,r=inf,res=inf;
	while(l<=r){
		int mid=(l+r)>>1;
		if(chk(mid)) r=mid-1,res=mid;
		else l=mid+1;
	}
	cout<<res<<'\n';
}
/*
5 5 10
0
358
1281
5298
5321
*/

标签:va,手持,joisc2017,int,sum,vb,else,cost,花火
From: https://www.cnblogs.com/Cyan0826/p/18372577

相关文章

  • STM32自制手持小风扇实验
    1.1介绍:实验功能说明:功能(1)按一下按键小风扇开启,再按一下关闭。功能(2)按一下按键小风扇一档风速,再按一下二挡,依次三挡…关闭。按键模块说明:按下S输出低电平电机驱动一体模块说明:VG引脚供电,AB是信号控制引脚,PWM可以调速正转控制:B低电平,A高电平反转控制:B高电平,A低电平1.......
  • [JOISC2017] Cultivation
    link。不是,怎么四方跑得飞快啊?成最优解了?有人会卡吗?鉴定为剪枝太多导致的。一个出发点不太一样的思路。假设上下左右各被操作了\(U,D,L,R\)次。我们考虑一个点\((x,y)\)不被感染的条件是初始时\([x-D,x+U]\times[y-R,y+L]\)这个矩形内没有任何感染点。考虑扣出所有中间......
  • joisc2017 D3T1 长途巴士 题解
    joisc2017D3T1长途巴士题解这是学校ACM欢乐赛的题,赛时想到做法了,但是因为我各种唐诗没写出来翻了转化题面我们发现,只可以踢掉检查站前面一个连续段的接水人,并且不能踢掉司机,考虑画出对整个路程表示的线段上图几个小点是检查点,考虑在每个检查点之前踢掉一段的人,容易发......
  • 北斗防爆手持终端在化工厂的安全性能分析
    北斗防爆手持终端在化工厂中的应用显著提升了安全性能,其卓越的防爆设计、高精度定位与监控功能、实时通信能力以及多功能集成特性,共同构筑了化工厂安全生产的坚实防线,确保了巡检人员与设备在复杂环境下的安全作业与高效管理。北斗防爆手持终端在化工厂中的安全性能表现卓越,主......
  • 常用 Docker 命令和配置指南 新手几乎够用 老手持续更新
    容器管理命令查看容器:查看所有已启动/未启动的容器:dockerps-a查看所有已启动的容器:dockerps启动和停止容器:启动容器:dockerstart容器ID停止容器:dockerstop容器ID重启容器:dockerrestart容器ID删除容器:删除容器:dockerrm容器ID镜像管理命令......
  • 《与光重聚》 —— 属于"他"的夏日花火
    题目是歌曲名称,from《夏日花火》(国产galgame;视觉小说「夏日花火」原声音乐集-dizzylab  PV视频因为被平衡树制裁了,所以心血来潮写这篇文章,姑且算是练笔吧(毕竟好久不写鲜花了;游戏本体发行时间:2022年10月28日,目前无DLC(永远的遗憾; 游戏背景设计是DL24,本人也是因此发现......
  • Agilent 安捷伦 N9342C 手持式频谱分析仪
    Agilent安捷伦N9342C手持式频谱分析仪N9342C手持式7GHz频谱分析仪专为现场测试而设计,无论是安装和维护射频系统,现场进行故障诊断,监测射频环境还是分析干扰,都可以为您提供快速、精确的测量。它具有同类最佳的显示平均噪声电平(DANL),使您能够对频谱进行全面分析;无与伦比的扫......
  • 谈一谈手持万用表,优利德,胜利,是德科技,高美,日置
    入坑万用表有两年了,总结下我这两年入坑的经验1.绕不开的福禄克,15B系列性能是真的差,但是做工真的好,算是做工最好的,速度慢,不过外壳和PCB做工本人觉的是最好的。福禄克算是比较贵的,17X系列,87V系列这俩系列唯二推荐的,其他系列除非收藏爱好不建议搞,F187停产了,估计是都用了MSP430单片......
  • rfid手持终端定制_工业/医用智能PDA手持终端方案
    手持终端产品是一款在性能和适用领域方面表现出色的安卓设备。它拥有高速流畅的运行性能、大容量存储、高端的扫描头,能够实现全网通数据连接,支持双频局域网通信,提供稳定的连接性能和持续快速的响应时。这款产品可以应用于多种严苛的环境,如医院、物流运输、零售配送和资产盘点等......
  • 气体检测仪定制_气体检测仪手持终端|便携式多种气体检测仪方案厂家
    手持气体检测仪终端是一种用于检测易燃易爆或有毒有害气体的便携式装置。它可以有效地防护人们免受可燃气体、有毒气体和缺氧等气体对健康造成的危害。在工程施工中,如果各类气体的浓度过高或过低,都可能对人体健康造成危害甚至引发爆炸等事故。因此,手持气体检测仪终端的使用显得......