博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
AtCoder ABC 076D - AtCoder Express
阅读量:4946 次
发布时间:2019-06-11

本文共 2789 字,大约阅读时间需要 9 分钟。

传送门:

本题是一个运动学问题——匀变速运动。

一个质点,从静止开始运动。按照速度限制,可将运动划分成n个阶段,第i个阶段的时间为ti s,速度上限为vi m/s。已知这个质点的加速度大小只取0或±1m/s2。以及,质点在最初和最终的时刻速度为0。求质点的最大位移。

以下变量均采用国际单位制。

对于运动某一个阶段(例如第i个阶段),可以分成三个子阶段:匀加速运动、匀速运动和匀减速运动。记三个子阶段的时间分别为inckepdec,则inc+kep+dec=t[i]。记下一个阶段的限速为lim,则:

  1. 匀加速阶段:inc=min{
    vi-cur,(lim+t[i]-cur)/2,t[i]};
  2. 匀减速阶段:dec=max{0,cur+inc-lim};
  3. 匀速阶段:kep=t[i]-inc-dec

于是,分别对这三段时间计算位移,求和即可。时间复杂度为O(n2),空间复杂度为O(n)。

参考程序如下:

#include 
#define MAX_N 101double t[MAX_N], v[MAX_N];double max(double a, double b){ return a > b? a: b;}double min(double a, double b){ return a < b? a: b;}int main(void){ int n; scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%lf", &t[i]); for (int i = 0; i < n; i++) scanf("%lf", &v[i]); double cur = 0.; double ans = 0.; for (int i = 0; i < n; i++) { double inc, kep, dec; double lim = 1.E8; double tmp = 0.; for (int j = i + 1; j <= n; j++) { lim = min(lim, v[j] + tmp); tmp += t[j]; } inc = min(v[i] - cur, (lim + t[i] - cur) * .5); inc = min(inc, t[i]); dec = max(0., cur + inc - lim); kep = t[i] - inc - dec; ans += .5 * (cur * 2. + inc) * inc; ans += (cur + inc) * kep; ans += .5 * ((cur + inc) * 2. - dec) * dec; cur += inc; cur -= dec; } printf("%f\n", ans); return 0;}

本题也可以从以下角度考虑:

仅考虑一个区间:若在时间区间[l,r]上的速度上限为v,则在整个时间区间[0,T]上,速度上限函数为

$$f(t)=\begin{cases} v+(l-t),0\le t<l\\v,l\le t\le r\\v+(t-r),r<t\le T\end{cases}$$

其中,$T=\sum_{i=1}^{n}t_i$。

对于阶段i,对应的时间区间为$[\sum_{j=1}^{i-1}t_j , \sum_{j=1}^{i}t_j ]$,速度上限为vi,相应的速度上限函数记为fi(t)。考虑所有的区间,则速度上限函数为$f(t)=\min\{t,T-t,f_{i}(t)|1\le i\le n\}$。

由于viti均是正整数,因此可以将t轴的最小单位设置为Δt=0.5s。可以假定从0时刻开始,在每一个Δt=0.5s内,质点的加速度是恒定的。则以Δt=0.5s为单位,用f(t)刻画质点运动的v-t图像,并用加速度的限制条件修正v(t)。通过质点运动的v-t图像计算其最大位移(即v-t曲线与t轴围成的图形面积)。时间复杂度为O(nT),空间复杂度为O(n+T)。

参考程序如下:

#include 
#define MAX_N 100#define MAX_T 40000int t[MAX_N];double v[MAX_N], f[MAX_T];double min(double a, double b){ return a < b? a: b;}int main(void){ int n; scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d", &t[i]); for (int i = 0; i < n; i++) scanf("%lf", &v[i]); for (int i = 0; i < MAX_T; i++) f[i] = 1.E8; int tot = 0; for (int i = 0; i < n; i++) { t[i] *= 2; for (int j = tot; j <= tot + t[i]; j++) f[j] = min(f[j], v[i]); tot += t[i]; } f[0] = f[tot] = 0.; for (int i = 1; i <= tot; i++) f[i] = min(f[i], f[i - 1] + .5); for (int i = tot - 1; i >= 0; i--) f[i] = min(f[i], f[i + 1] + .5); double ans = 0.; for (int i = 0; i < tot; i++) ans += .25 * (f[i] + f[i + 1]); printf("%f\n", ans); return 0;}

 

转载于:https://www.cnblogs.com/siuginhung/p/7749977.html

你可能感兴趣的文章
人情与面子
查看>>
JS加载获取父窗体传递的参数
查看>>
NumPy 学习笔记(三)
查看>>
选择排序详解
查看>>
SpringCloud系列五:Ribbon 负载均衡(Ribbon 基本使用、Ribbon 负载均衡、自定义 Ribbon 配置、禁用 Eureka 实现 Ribbon 调用)...
查看>>
【转】UML的9种图例解析
查看>>
python2.x到python3.x函数变化
查看>>
CSS之Position详解
查看>>
javascript面向对象重写右键菜单事件
查看>>
UVa10791 - Minimum Sum LCM
查看>>
Android底部导航栏——FrameLayout + RadioGroup
查看>>
NOI2016 优秀的拆分 后缀数组
查看>>
Java消息服务
查看>>
Jtester使用
查看>>
详解CSS样式的position属性
查看>>
Python机器学习(5)——朴素贝叶斯分类器
查看>>
Mac 10.12连接iSCSI硬盘软件iSCSI Initiator X
查看>>
ffmpeg获取文件的总时长(mp3/mp4/flv等)
查看>>
Python virtualenvwrapper在Win下的安装和管理
查看>>
费马小定理
查看>>