[NOIP2018 (PJ)] car ferry

Topic Link

The meaning of problems

  There $ $ n-th student waiting for the bus, each student start at some time from the other vehicles, at least adjacent the interval between car twice $ m $ minutes. Kaikai scheduled departure time may be arbitrary, minimum and so all the students and the time of the car.

analysis

  This question can think of is the first dynamic programming

  Obviously must first sort the time everyone began to wait

  Assuming that $ f [i] $ is the minimum waiting time before the $ i $ individuals have left, since to do so on the departure time with each person to determine the car good time, so consider adding a dimension

  When the set $ f [i] [j] $ personal for the first $ i $ $ j $ waiting for the first minute, wait a minimum of time before the $ i $ individuals have time and just leave the car

  We can enumerate $ i $ and $ j $, while the value of $ i $ classmate later updated

  At this time, the first $ k \, (k> i) $ $ individual time waiting for the bus is now $ $ max (t [i] + j + mt [k], 0) $

  所以 $f[k][now]=f[i][j]+\sum\limits_{x=i+1}^k (now+t[k]-t[x])$

  However, a one-dimensional summation will increase time complexity, the pretreatment may then be first $ t [i] $ prefix and $ s [i] $

  然后 $f[k][now]=f[i][j]+(now+t[k]) \times (k-i)-(s[k]-s[i])$

  Finally, find the minimum value in the case of $ n $ classmate have left in

  Time complexity is $ O (n ^ 2 m) $, but actually much better than this small

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 505

int n, m, ans = inf;
int t[N], s[N], f[N][N];

int main() {
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++)
        scanf("%d", t + i);
    sort(t + 1, t + n + 1);
    for (int i = 1; i <= n; i++)
        s[i] = s[i - 1] + t[i];
    t[0] = -inf;
    memset(f, 0x3f, sizeof f);
    f[0][0] = 0;
    for (int i = 0; i <= n; i++) {
        int mj = min(m - 1, t[i + 1] - t[i]);
        for (int j = 0; j <= mj; j++)
            if (f[i][j] != inf)
                for (int k = 1; i + k <= n; k++) {
                    int now = max(t[i] + j + m - t[i + k], 0);
                    f[i + k][now] = min(f[i + k][now],
                        f[i][j] + (t[i + k] + now) * k - (s[i + k] - s[i]));
                }
    }
    for (int i = 0; i < m; i++)
        ans = min(ans, f[n][i]);
    printf("%d\n", ans);

    return 0;
}
View Code

Guess you like

Origin www.cnblogs.com/Pedesis/p/11030178.html