传送门:http://abc076.contest.atcoder.jp/tasks/abc076_d

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

一个质点,从静止开始运动。按照速度限制,可将运动划分成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 <stdio.h>
#define MAX_N 101 double 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 = ; i < n; i++)
scanf("%lf", &t[i]);
for (int i = ; i < n; i++)
scanf("%lf", &v[i]);
double cur = .;
double ans = .;
for (int i = ; i < n; i++) {
double inc, kep, dec;
double lim = .E8;
double tmp = .;
for (int j = i + ; j <= n; j++) {
lim = min(lim, v[j] + tmp);
tmp += t[j];
}
inc = min(v[i] - cur, (lim + t[i] - cur) * .);
inc = min(inc, t[i]);
dec = max(., cur + inc - lim);
kep = t[i] - inc - dec;
ans += . * (cur * . + inc) * inc;
ans += (cur + inc) * kep;
ans += . * ((cur + inc) * . - dec) * dec;
cur += inc;
cur -= dec;
}
printf("%f\n", ans);
return ;
}

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

仅考虑一个区间:若在时间区间[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 <stdio.h>
#define MAX_N 100
#define MAX_T 40000 int 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 = ; i < n; i++)
scanf("%d", &t[i]);
for (int i = ; i < n; i++)
scanf("%lf", &v[i]);
for (int i = ; i < MAX_T; i++)
f[i] = .E8;
int tot = ;
for (int i = ; i < n; i++) {
t[i] *= ;
for (int j = tot; j <= tot + t[i]; j++)
f[j] = min(f[j], v[i]);
tot += t[i];
}
f[] = f[tot] = .;
for (int i = ; i <= tot; i++)
f[i] = min(f[i], f[i - ] + .);
for (int i = tot - ; i >= ; i--)
f[i] = min(f[i], f[i + ] + .);
double ans = .;
for (int i = ; i < tot; i++)
ans += . * (f[i] + f[i + ]);
printf("%f\n", ans);
return ;
}

AtCoder ABC 076D - AtCoder Express的更多相关文章

  1. ATCODER ABC 099

    ATCODER ABC 099 记录一下自己第一场AK的比赛吧...虽然还是被各种踩... 只能说ABC确实是比较容易. A 题目大意 给你一个数(1~1999),让你判断它是不是大于999. Sol ...

  2. Atcoder ABC 141

    Atcoder ABC 141 A - Weather Prediction SB题啊,不讲. #include<iostream> #include<cstdio> #inc ...

  3. Atcoder ABC 139E

    Atcoder ABC 139E 题意: n支球队大循环赛,每支队伍一天只能打一场,求最少几天能打完. 解法: 考虑抽象图论模型,既然一天只能打一场,那么就把每一支球队和它需要交手的球队连边. 求出拓 ...

  4. Atcoder ABC 139D

    Atcoder ABC 139D 解法: 等差数列求和公式,记得开 $ long long $ CODE: #include<iostream> #include<cstdio> ...

  5. Atcoder ABC 139C

    Atcoder ABC 139C 题意: 有 $ n $ 个正方形,选择一个起始位置,使得从这个位置向右的小于等于这个正方形的高度的数量最多. 解法: 简单递推. CODE: #include< ...

  6. Atcoder ABC 139B

    Atcoder ABC 139B 题意: 一开始有1个插口,你的插排有 $ a $ 个插口,你需要 $ b $ 个插口,问你最少需要多少个插排. 解法: 暴力模拟. CODE: #include< ...

  7. Atcoder ABC 139A

    Atcoder ABC 139A 题意: 给你两个字符串,记录对应位置字符相同的个数 $ (n=3) $ 解法: 暴力枚举. CODE: #include<iostream> #inclu ...

  8. atcoder abc 244

    atcoder abc 244 D - swap hats 给定两个 R,G,B 的排列 进行刚好 \(10^{18}\) 次操作,每一次选择两个交换 问最后能否相同 刚好 \(10^{18}\) 次 ...

  9. AtCoder ABC 250 总结

    AtCoder ABC 250 总结 总体 连续若干次一样的结果:30min 切前 4 题,剩下卡在 T5 这几次卡在 T5 都是一次比一次接近, 什么 dp 前缀和打挂,精度被卡,能水过的题连水法都 ...

随机推荐

  1. Spring源代码解析和配置文件载入

    Spring类的继承结构图: Spring运用了大量的模板方法模式和策略模式,所以各位看源代码的时候,务必留意,每个继承的层次都有不同的作用.然后将同样的地方抽取出来,依赖抽象将不同的处理依照不同的策 ...

  2. HTML文档基础

    一.HTML(Hyper Text Markup Language超文本标记语言)是一种用来制作超文本文档的简单标记语言,HTML在正文的文本中编写各种标记,通过Web浏览器进行编译和运行才干正确显示 ...

  3. UVa 1584 Circular Sequence(环形串最小字典序)

    题意  给你一个环形串   输出它以某一位为起点顺时针得到串的最小字典序 直接模拟   每次后移一位比較字典序就可以  注意不能用strcpy(s+1,s)这样后移  strcpy复制地址不能有重叠部 ...

  4. Android热更新实现原理

    最近Android社区的氛围很不错嘛,连续放出一系列的android动态加载插件和热更新库,这篇文章就来介绍一下Android中实现热更新的原理. ClassLoader 我们知道Java在运行时加载 ...

  5. Spark底层原理简化版

    目录 Spark SQL/DF的执行过程 集群运行部分 Aggregation Join Shuffle Tungsten 内存管理机制 缓存敏感计算(Cacheaware computation) ...

  6. c#调用带有自定义表结构的存储过程

    1.新建自定义表结构 CREATE TYPE [dbo].[HBForHBGHDR] AS TABLE( [序号] [int] NULL, [客户编号] [varchar](15) NULL ) GO ...

  7. [转] 理解 Dubbo SPI 扩展机制

    写在前面 最近接触了 gRPC 体会到虽然众多 RPC 框架各有各的特点但是他们提供的特性和功能有很多的相似之处 , 这就说明他们面对同样的分布式系统带来的问题.从 2016 年左右开始接触到 dub ...

  8. vue 中数据没有同步渲染的解决方法

    今天在做一个页面,遇到一个数据渲染不同步的问题,如下: 代码如下:原理:点击时,对应的banklist 的选项选项变为 true 选中状态 html: <div class="PayO ...

  9. vs2008bin下Debug bll Release文件 obj下的Debug bll Release文件区别

    Bin目录用来存放编译的结果,bin是二进制binrary的英文缩写,因为最初C编译的程序文件都是二进制文件,它有Debug和Release两个版本,分别对应的文件夹为bin/Debug和bin/Re ...

  10. bootstrap的栅格系统和响应式工具

    关于bootstrap的响应式布局,昨天看了杨老师的视频教学https://www.bilibili.com/video/av18357039豁然开朗,在这里记录一下 一:meta标签的引用 < ...