解法一

二分至少需要多少秒,设至少需要 m m m秒。
设 d p i , 0 dp_{i,0} dpi,0​为第 i i i个人先往右,碰到第 i + 1 i+1 i+1个人之后再往左, m m m秒内第 i i i个人至多能往右走多远。
设 d p i , 1 dp_{i,1} dpi,1​为第 i i i个人先往左,碰到第 i − 1 i-1 i−1个人之后再往右, m m m秒内第 i i i个人至多能往右走多远。
初始状态为 d p 1 , 0 = d p 1 , 1 = m dp_{1,0}=dp_{1,1}=m dp1,0​=dp1,1​=m。
然后分析转移:
1.第 i − 1 i-1 i−1个人先往右,第 i i i个人先往左,则他们会在第 a i − a i − 1 2 \frac{a_i-a_{i-1}}{2} 2ai​−ai−1​​秒再两个人的中点相遇,这要求 d p i − 1 , 0 ≥ a i − a i − 1 2 dp_{i-1,0}\ge \frac{a_i-a_{i-1}}{2} dpi−1,0​≥2ai​−ai−1​​才能转移,随后第 i i i个人要先跑 a i − a i − 1 2 \frac{a_i-a_{i-1}}{2} 2ai​−ai−1​​秒回到点 a i a_i ai​,再继续往右跑,有:

if(dp[i-1][0]>=(a[i]-a[i-1])/2)dp[i][1]=max(dp[i][1],m-(a[i]-a[i-1]));

2.第 i − 1 i-1 i−1个人先往右,第 i i i个人先往右,再他们同时往右的过程中他们的距离始终为 a i − a i − 1 a_i-a_{i-1} ai​−ai−1​,这要求第 i − 1 i-1 i−1个人往右跑的最后 a i − a i − 1 2 \frac{a_i-a_{i-1}}{2} 2ai​−ai−1​​秒第 i i i个人必须往左他们才能相遇,有:

if(dp[i-1][0]>=(a[i]-a[i-1])/2)dp[i][0]=max(dp[i][0],dp[i][0]-(a[i]-a[i-1])/2);

3.第 i − 1 i-1 i−1个人先往左,第 i i i个人先往右, m m m秒后第 i − 1 i-1 i−1个人一定停留再点 a i − 1 + d p i − 1 , 1 a_{i-1}+dp_{i-1,1} ai−1​+dpi−1,1​,只需要保证第 i i i个人至少往左跑 a i − ( a i − 1 + d p i − 1 , 1 ) a_i-(a_{i-1}+dp_{i-1,1}) ai​−(ai−1​+dpi−1,1​)步即可,剩下的步数都可用于往右跑一个来回 ,有:

if(m>=a[i]-a[i-1]-dp[i-1][1])dp[i][0]=max(dp[i][0],(m-(a[i]-a[i-1]-dp[i-1][1]))/2));

4.第 i − 1 i-1 i−1个人先往左,第 i i i个人先往左,这种情况可以推测第 i − 1 i-1 i−1个人至少需要往左跑 m − d p i − 1 , 1 2 \frac{m-dp_{i-1,1}}{2} 2m−dpi−1,1​​步,同样在他们同时往左的过程中距离始终为 a i − a i − 1 a_i-a_{i-1} ai​−ai−1​,这要求第 i − 1 i-1 i−1个人往右跑的前 a i − a i − 1 2 \frac{a_i-a_{i-1}}{2} 2ai​−ai−1​​秒第 i i i个人继续保持往左跑 i − 1 i-1 i−1和 i i i才能相遇,则第 i i i个人至少需要往左跑 m − d p i − 1 , 1 2 + a i − a i − 1 2 \frac{m-dp_{i-1,1}}{2}+\frac{a_i-a_{i-1}}{2} 2m−dpi−1,1​​+2ai​−ai−1​​步,剩余步数先跑回点 a i a_i ai​再继续往右,有:

if((m-dp[i-1][1])/2+(a[i]-a[i-1])/2<=m)dp[i][1]=max(dp[i][1],m-2*((m-dp[i-1][1])/2+(a[i]-a[i-1])/2)));

时间复杂度 O ( n l o g ( n ) ) O(nlog(n)) O(nlog(n))。

#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
typedef unsigned long long ull;
typedef long long ll;
#define rep(i,l,r) for(int i=l;i<=r;i++)
#define nep(i,r,l) for(int i=r;i>=l;i--)
void sc(int &x){scanf("%d",&x);}
void sc(int &x,int &y){scanf("%d%d",&x,&y);}
void sc(int &x,int &y,int &z){scanf("%d%d%d",&x,&y,&z);}
void sc(ll &x){scanf("%lld",&x);}
void sc(ll &x,ll &y){scanf("%lld%lld",&x,&y);}
void sc(ll &x,ll &y,ll &z){scanf("%lld%lld%lld",&x,&y,&z);}
void sc(char *x){scanf("%s",x);}
void sc(char *x,char *y){scanf("%s%s",x,y);}
void sc(char *x,char *y,char *z){scanf("%s%s%s",x,y,z);}
void out(int x){printf("%d\n",x);}
void out(ll x){printf("%lld\n",x);}
void out(int x,int y){printf("%d %d\n",x,y);}
void out(ll x,ll y){printf("%lld %lld\n",x,y);}
void out(int x,int y,int z){printf("%d %d %d\n",x,y,z);}
void out(ll x,ll y,ll z){printf("%lld %lld %lld\n",x,y,z);}
using namespace std;
#define inf 0x3f3f3f3f
const int N=3e5+5;
int n,a[N];
int dp[N][2];
void update(int &x,int y)
{x=max(x,y);
}
bool judge(int m)
{memset(dp,-inf,sizeof(dp));dp[1][0]=dp[1][1]=m;for(int i=2;i<=n;i++){bool flag=false;if(dp[i-1][0]>=(a[i]-a[i-1])/2){update(dp[i][1],m-(a[i]-a[i-1]));update(dp[i][0],dp[i-1][0]-(a[i]-a[i-1])/2);flag=true;}if(m>=a[i]-a[i-1]-dp[i-1][1]){update(dp[i][0],(m-(a[i]-a[i-1]-dp[i-1][1]))/2);flag=true;}if((m-dp[i-1][1])/2+(a[i]-a[i-1])/2<=m){update(dp[i][1],m-2*((m-dp[i-1][1])/2+(a[i]-a[i-1])/2));flag=true;}if(!flag) return false;}return true;
}
int main()
{//freopen("1.in","r",stdin);freopen("1.out","w",stdout);sc(n);rep(i,1,n) sc(a[i]);int l=0,r=(a[n]-a[1])/2,ans;while(l<=r){int m=l+r>>1;if(judge(m)) ans=m,r=m-1;else l=m+1;}out(ans);
}

解法二

用 s i = L s_i=L si​=L表示第 i i i个人先往左,碰到第 i − 1 i-1 i−1个人之后再往右。
用 s i = R s_i=R si​=R表示第 i i i个人先往右,碰到第 i + 1 i+1 i+1个人之后再往左。
特别的,有 s 1 = R , s n = L s_1=R,s_n=L s1​=R,sn​=L。
将 s 1 s 2 . . . s n s_1s_2...s_n s1​s2​...sn​按如下方式分段:
R . . . R L . . . L , R . . . R L . . . L , . . . . R...RL...L,R...RL...L,.... R...RL...L,R...RL...L,....

设 s a . . . s b s c . . . s d = R . . . R L . . . L s_a...s_bs_c...s_d=R...RL...L sa​...sb​sc​...sd​=R...RL...L,则对于 i ∈ [ a , d ) i\in[a,d) i∈[a,d)满足 i i i和 i + 1 i+1 i+1至少相遇一次的时间为 F ( a , b , c , d ) = A c − A b 2 + m a x ( A b − A a 2 , A d − A c 2 ) = m a x ( A c − A a , A d − A b ) 2 F(a,b,c,d)=\frac{A_c-A_b}{2}+max(\frac{A_b-A_a}{2},\frac{A_d-A_c}{2})\\=\frac{max(A_c-A_a,A_d-A_b)}{2} F(a,b,c,d)=2Ac​−Ab​​+max(2Ab​−Aa​​,2Ad​−Ac​​)=2max(Ac​−Aa​,Ad​−Ab​)​

对于 s a . . . s b s c . . . s d = R . . . R L . . . L s_a...s_bs_c...s_d=R...RL...L sa​...sb​sc​...sd​=R...RL...L和 s e . . . s f s g . . . s h = R . . . R L . . . L ( e = d + 1 ) s_e...s_fs_g...s_h=R...RL...L(e=d+1) se​...sf​sg​...sh​=R...RL...L(e=d+1),对于 i ∈ [ a , h ) i\in[a,h) i∈[a,h)满足 i i i和 i + 1 i+1 i+1都碰撞一次的时间为 m a x ( F ( a , b , c , d ) , F ( e , f , g , h ) , A g − A b 2 ) max(F(a,b,c,d),F(e,f,g,h),\frac{A_g-A_b}{2}) max(F(a,b,c,d),F(e,f,g,h),2Ag​−Ab​​)( d , e d,e d,e碰撞的时间为 A g − A b 2 \frac{A_g-A_b}{2} 2Ag​−Ab​​)

于是可以设 d p d , b dp_{d,b} dpd,b​为第 1... d 1...d 1...d的位置划分好后,上一个 R R R出现的位置为 b b b,对于 i ∈ [ 1 , d ) i\in[1,d) i∈[1,d)满足 i i i和 i + 1 i+1 i+1都碰撞一次所需要的最小时间。
有转移
d p h , f = m i n { d p h , f , m a x ( d p d , b , A f + 1 − A b 2 , F ( d + 1 , f , f + 1 , h ) ) } dp_{h,f}=min\{dp_{h,f},max(dp_{d,b},\frac{A_{f+1}-A_b}{2},F(d+1,f,f+1,h))\} dph,f​=min{dph,f​,max(dpd,b​,2Af+1​−Ab​​,F(d+1,f,f+1,h))}
可以得到 O ( n 4 ) O(n^4) O(n4)的 d p dp dp。

现在证明最优的情况不会出现 s i − 1 s i s i + 1 s i + 2 = R L L L 、 R R R L 、 R L R L s_{i-1}s_is_{i+1}s_{i+2}=RLLL、RRRL、RLRL si−1​si​si+1​si+2​=RLLL、RRRL、RLRL的情况(结论1):

若 s i − 1 s i s i + 1 s i + 2 = R L L L s_{i-1}s_is_{i+1}s_{i+2}=RLLL si−1​si​si+1​si+2​=RLLL,则 ( i − 1 , i ) , ( i , i + 1 ) , ( i + 1 , i + 2 ) (i-1,i),(i,i+1),(i+1,i+2) (i−1,i),(i,i+1),(i+1,i+2)都碰撞一次所花费的时间为 A i + 2 − A i − 1 2 \frac{A_{i+2}-A_{i-1}}{2} 2Ai+2​−Ai−1​​,第 i + 1 i+1 i+1个人和第 i + 2 i+2 i+2个人会在点 A i − 1 + A i + 2 2 \frac{A_{i-1}+A_{i+2}}{2} 2Ai−1​+Ai+2​​碰撞。

若 s i − 1 s i s i + 1 s i + 2 = R R R L s_{i-1}s_is_{i+1}s_{i+2}=RRRL si−1​si​si+1​si+2​=RRRL, ( i − 1 , i ) , ( i , i + 1 ) , ( i + 1 , i + 2 ) (i-1,i),(i,i+1),(i+1,i+2) (i−1,i),(i,i+1),(i+1,i+2)都碰撞一次花费的时间也为 A i + 2 − A i − 1 2 \frac{A_{i+2}-A_{i-1}}{2} 2Ai+2​−Ai−1​​,第 i − 1 i-1 i−1个人和第 i i i个人会在点 A i − 1 + A i + 2 2 \frac{A_{i-1}+A_{i+2}}{2} 2Ai−1​+Ai+2​​碰撞。

若 s i − 1 s i s i + 1 s i + 2 = R L R L s_{i-1}s_is_{i+1}s_{i+2}=RLRL si−1​si​si+1​si+2​=RLRL, ( i − 1 , i ) , ( i , i + 1 ) , ( i + 1 , i + 2 ) (i-1,i),(i,i+1),(i+1,i+2) (i−1,i),(i,i+1),(i+1,i+2)都碰撞一次花费的时间也为 A i + 2 − A i − 1 2 \frac{A_{i+2}-A_{i-1}}{2} 2Ai+2​−Ai−1​​,第 i i i个人和第 i + 1 i+1 i+1个人会在点 A i − 1 + A i + 2 2 \frac{A_{i-1}+A_{i+2}}{2} 2Ai−1​+Ai+2​​碰撞。

若将上述情况改为 s i − 1 s i s i + 1 s i + 2 = R R L L s_{i-1}s_is_{i+1}s_{i+2}=RRLL si−1​si​si+1​si+2​=RRLL,此时 ( i − 1 , i ) , ( i , i + 1 ) , ( i + 1 , i + 2 ) (i-1,i),(i,i+1),(i+1,i+2) (i−1,i),(i,i+1),(i+1,i+2)都碰撞一次的时间花费比上述两种情况都要更优, i i i和 i + 1 i+1 i+1碰撞后,由于 i − 1 , i i-1,i i−1,i都在向右运行, i + 1 , i + 2 i+1,i+2 i+1,i+2都在向左运行,故在 i , i + 1 i,i+1 i,i+1没改变方向时 i − 1 , i i-1,i i−1,i的距离始终为 A i − A i − 1 A_i-A_{i-1} Ai​−Ai−1​, i + 1 , i + 2 i+1,i+2 i+1,i+2保持的距离始终为 A i + 2 − A i + 1 A_{i+2}-A_{i+1} Ai+2​−Ai+1​,故时间花费为:
A i + 1 − A i 2 + m a x ( A i + 2 − A i + 1 2 , A i − A i − 1 2 ) = m a x ( A i + 2 − A i , A i + 1 − A i − 1 ) 2 ≤ A i + 2 − A i − 1 2 \frac{A_{i+1}-A_{i}}{2}+max(\frac{A_{i+2}-A_{i+1}}{2},\frac{A_{i}-A_{i-1}}{2}) \\=\frac{max(A_{i+2}-A_{i},A_{i+1}-A_{i-1})}{2}\le \frac{A_{i+2}-A_{i-1}}{2} 2Ai+1​−Ai​​+max(2Ai+2​−Ai+1​​,2Ai​−Ai−1​​)=2max(Ai+2​−Ai​,Ai+1​−Ai−1​)​≤2Ai+2​−Ai−1​​

结论1和 s 1 = R , s n = L s_1=R,s_n=L s1​=R,sn​=L,则最优情况下不会出现连续三个状态相等的情况。
于是对于 d p d , b dp_{d,b} dpd,b​, b b b要么等于 d − 1 d-1 d−1,要么等于 d − 2 d-2 d−2,可以分别设为 d p d , 0 / 1 dp_{d,0/1} dpd,0/1​。
上述方程就被优化到了 O ( n ) O(n) O(n)。

#include<bits/stdc++.h>
typedef unsigned long long ull;
typedef long long ll;
#define inf 0x3f3f3f3f
#define rep(i,l,r) for(int i=l;i<=r;i++)
#define nep(i,r,l) for(int i=r;i>=l;i--)
void sc(int &x){scanf("%d",&x);}
void sc(int &x,int &y){scanf("%d%d",&x,&y);}
void sc(int &x,int &y,int &z){scanf("%d%d%d",&x,&y,&z);}
void sc(ll &x){scanf("%lld",&x);}
void sc(ll &x,ll &y){scanf("%lld%lld",&x,&y);}
void sc(ll &x,ll &y,ll &z){scanf("%lld%lld%lld",&x,&y,&z);}
void sc(char *x){scanf("%s",x);}
void sc(char *x,char *y){scanf("%s%s",x,y);}
void sc(char *x,char *y,char *z){scanf("%s%s%s",x,y,z);}
void out(int x){printf("%d\n",x);}
void out(ll x){printf("%lld\n",x);}
void out(int x,int y){printf("%d %d\n",x,y);}
void out(ll x,ll y){printf("%lld %lld\n",x,y);}
void out(int x,int y,int z){printf("%d %d %d\n",x,y,z);}
void out(ll x,ll y,ll z){printf("%lld %lld %lld\n",x,y,z);}
using namespace std;
const int N=3e5+5;
int n,A[N],dp[N][2];
int F(int a,int b,int c,int d)
{return max(A[c]-A[a],A[d]-A[b]);
}
int main()
{sc(n);rep(i,1,n) sc(A[i]);memset(dp,inf,sizeof(dp));dp[1][0]=0;dp[2][0]=dp[2][1]=A[2]-A[1];A[0]=A[1];A[n+1]=A[n];//特别第A[1]可以看成一个LR//A[n]可以看成一个LR 因此把序列两边扩展一下for(int i=1;i<=n+1;i++)for(int j=0;j<=1;j++)if(dp[i][j]!=inf){int b=i-1-j;for(int f=i+1;f<=i+2&&f<=n;f++)for(int h=f+1;h<=f+2&&h<=n+1;h++)dp[h][f==h-2]=min(dp[h][f==h-2],max(dp[i][j],max(A[f+1]-A[b],F(i+1,f,f+1,h))));}out(min(dp[n+1][0],dp[n+1][1])/2);
}

ARC120E - 1D Party相关推荐

  1. [ARC120E]1D Party

    1D Party 题解 我们可以将原来的序列随时间变化转化成一个图像,纵轴代表时间,横轴代表 A A A的值. 那么我们可以得到这样一个图像: 其中不同颜色代表不同的点的运动路径. 由于要最优,我们肯 ...

  2. 理解透彻--802.1d,802.1w,802.1s与802.1q

    原文链接:http://blog.sina.com.cn/s/blog_9950926401018bj6.html 照片之类的就在原文链接里面看吧.这里就不复制啦. 算啦,我先简要总结一下: STP( ...

  3. 了解1D和3D卷积神经网络|Keras

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 译者|Arno 当我们说卷积神经网络(CNN)时,通常是指用于图像 ...

  4. android将矩阵转换成字节数组,android-使用OpenGL矩阵转换将纹理从“ 1D”映...

    (针对这个问题,我正在尝试研究解决this other one的想法) 如果我在内存中有一个标准的2D数组,其尺寸为width和height,则可以将其转换为一个长度为width * height的一 ...

  5. 手把手教你使用 1D 卷积和 LSTM 混合模型做 EEG 信号识别

    本文是由CSDN用户[Memory逆光]授权分享.主要介绍了使用 1D 卷积和 LSTM 混合模型做 EEG 信号识别.感谢Memory逆光! 内容包括:1. 数据集(1.1 数据集下载.1.2 数据 ...

  6. 1D target tensor expected, multi-target not supported

    pytorch 交叉熵损失计算时报错了: 1D target tensor expected, multi-target not supported if __name__ == '__main__' ...

  7. ValueError: Masked arrays must be 1-D

    ValueError: Masked arrays must be 1-D 使用numpy画散点图出现以上问题.(<机器学习-算法原理与编程实践>第7页) 原代码如下:

  8. 成功解决ValueError: Expected 2D array, got 1D array instead: Reshape your data either using array.reshap

    成功解决ValueError: Expected 2D array, got 1D array instead: Reshape your data either using array.reshap ...

  9. 《python机器学习经典实例》Expected 2D array, got 1D array instead和Reshape your data either using array.问题(已解决)

    问题描述: ValueError: Expected 2D array, got 1D array instead: array=[2.  1.5]. Reshape your data either ...

最新文章

  1. vue 全局排序_搞定VUE [ 一 ]
  2. 移动直播连麦实现思路:整体篇
  3. 昨天7月21号,笑笑又生病了
  4. c++思维导图_40+张最全Linux/C/C++思维导图,你确定不收藏?
  5. 小程序 php wecahtpay,PHP 微信公众号,小程序获取支付参数。微信支付
  6. 社区OpenJDK代码构建平台投入使用
  7. 华为NP课程笔记15-Eth-Trunk与高级VLAN
  8. arm嵌入式led灯闪烁实验报告_ARM嵌入式系统与应用实验报告
  9. 鬼压床、清明梦、外星劫持……睡眠麻痹症能够解释这些都市传说吗?
  10. win10笔记本,蓝牙耳机连接上电脑以后,耳机没有声音怎么办?
  11. 300多个地级市GDP及第一、二、三产业占比数据(1990-2021年)
  12. 应用调试(三)oops
  13. 二分法和三分法的用处和区别
  14. 百度云盘云知梦php_[云知梦]WEB前端开发_WEB前端新手入门视频教程[百度云盘]
  15. Windows Python PyTorch CUDA 11.7 TensorRT 环境配置
  16. 垂钓之王hd_如果收到网络钓鱼电子邮件该怎么办?
  17. 量子力学奇妙之旅-微扰论和变分法
  18. 深度学习-卷积神经网络(CNN)
  19. Xilinx MIG DDR3 控制器 Modelsim 仿真
  20. 交友网站Circl.es帮你找到另一半

热门文章

  1. Inkcanvas 放大缩小变换
  2. M2 MacBookAir售价是多少 M2 MacBookAir配置如何
  3. 【JAVA】项目开发团队分配管理软件
  4. Go开发 之 容器(数组Array、切片slice、映射map、列表list)
  5. 小米的抢购骗局+小米的抢购页面的源代码分析(二)文本数组的分析
  6. 这108道 JavaOOP 面试题 你是不是都会了?
  7. Excel中IF函数的使用
  8. python基础——数据可视化
  9. 网上商城系统面试时怎么说的思路
  10. 分销商城系统核心功能模块