• AtCoder ABC 076D


    传送门: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 = 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
    ", ans);
        return 0;
    }

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

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

    $$f(t)=egin{cases} v+(l-t),0le t<l\v,lle tle r\v+(t-r),r<tle Tend{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)|1le ile 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 = 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
    ", ans);
        return 0;
    }
  • 相关阅读:
    2018百度之星初赛B轮 rect
    八数码问题(九宫格重排) 利用康托展开 判重
    2018百度之星初赛A轮 度度熊拼三角
    2018百度之星初赛A轮 度度熊学队列
    MongoDB(课时22 唯一索引)
    MongoDB(课时21 索引)
    MongoDB(课时20 游标)
    MongoDB(课时19 数据删除)
    MongoDB(课时18 修改器)
    MongoDB(课时17 更新函数)
  • 原文地址:https://www.cnblogs.com/siuginhung/p/7749977.html
Copyright © 2020-2023  润新知