传送门: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. C++ 移位运算与进制转换 浅析

    移位运算包括"逻辑移位"(logical shift)和"算术移位"(arithmetic shift). 逻辑移位:移出去的位丢弃,空缺位(vacant bi ...

  2. 2014.8.12-AKKA和Actor model 分布式开发环境学习小结

    学习使用AKKA 断断续续有一年了. 眼下还是习惯用java来写akka以下的程序.对于原生的scala还是没有时间和兴趣去学习它. 毕竟学习一门语言须要兴趣和时间的. AKKA学习资源还是不算丰富. ...

  3. IOS7中动态计算UILable的高度

    .h文件 #import <UIKit/UIKit.h> @interface UILabel (ContentSize) - (CGSize)contentSize; @end .m文件 ...

  4. java 页面传输中文乱码解决方式

    post 中文乱码解决方案 接受数据的时候设置 request.setCharacterEncoding("utf-8");//编码必须和页面编码一致 页面设置 <%@pag ...

  5. luogu1026 统计单词个数

    题目大意 给出一个长度不超过200的由小写英文字母组成的字母串(约定;该字串以每行20个字母的方式输入,且保证每行一定为20个).要求将此字母串分成k份(1< k< =40),且每份中包含 ...

  6. SQL排他锁的解决方案

    SQL排他锁的解决方案 分类: 事务与锁 数据库管理维护2009-04-28 22:41 680人阅读 评论(0) 收藏 举报 sql数据库database服务器killdisk 问题描述: 我有一个 ...

  7. 请问在C#的Winform下如何用正则表达式限制用户只能在textBox中输入18位的身份证号码。

    请问在C#的Winform下如何用正则表达式限制用户只能在textBox中输入18位的身份证号码. 2013-06-18 11:07会飞的鱼儿18 | 分类:C#/.NET | 浏览101次 不能有空 ...

  8. 【BZOJ 1601】 灌水

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=1601 [算法] 最小生成树 [代码] #include<bits/stdc++ ...

  9. 803E

    dp dp[i][j]表示到了i赢和输的差为j 如果这位是?向dp[i-1][j-1],dp[i-1][j],dp[i-1][j+1]转移,如果是W向dp[i-1][j-1]转移,如果是L向dp[i- ...

  10. openstack 性能优化极致