传送门: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. 3D数学读书笔记——多坐标系和向量基础

    本系列文章由birdlove1987编写,转载请注明出处. 文章链接: http://blog.csdn.net/zhurui_idea/article/details/24662453 第一个知识点 ...

  2. 菜鸟nginx源代码剖析 配置与部署篇(一) 手把手实现nginx &quot;I love you&quot;

    菜鸟nginx源代码剖析 配置与部署篇(一) 手把手配置nginx "I love you" Author:Echo Chen(陈斌) Email:chenb19870707@gm ...

  3. 小白学开发(iOS)OC_ 字符串写入文件(2015-08-13)

    // //  main.m //  字符串写入文件 // //  Created by admin on 15/8/13. //  Copyright (c) 2015年 admin. All rig ...

  4. velocity简单样例

    velocity简单样例整体实现须要三个步骤,详细例如以下: 1.创建一个Javaproject 2.导入须要的jar包 3.创建须要的文件 ============================= ...

  5. oc62--block1

    // // main.m // Block的应用场景 // typedef void (^workBlock)(); #import <Foundation/Foundation.h> / ...

  6. oc38--类工厂方法在继承中

    // Person.h #import <Foundation/Foundation.h> @interface Person : NSObject @property int age; ...

  7. Git 少用 Pull 多用 Fetch 和 Merge 【已翻译100%】【转】

    本文转载自:https://www.oschina.net/translate/git-fetch-and-merge?lang=chs&page=1# 本文有点长而且有点乱,但就像Mark ...

  8. How to use shared model by git in sql source control of red gate

    1.clone the git repository for datbase 2.open sql source control window and select the target databa ...

  9. bzoj1030 文本生成器(AC自动机+dp)

    1030: [JSOI2007]文本生成器 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 4777  Solved: 1986[Submit][Stat ...

  10. Python 33(1) UDP协议 数据报协议 socketsever模块

    一:基于UDP协议通信的套接字  基于UDP协议 只要是套接字,在开发的过程中一定要有服务端和客户端. UDP协议说的就是数据报协议,也就是说,基于UDP协议来发数据,每发一个数据,都是带有报头的数据 ...