zoukankan      html  css  js  c++  java
  • 摆渡车

    题目描述:
    \(n\) 名同学要乘坐摆渡车从人大附中前往人民大学,第 iii 位同学在第 \(t_i\) 分钟去 等车。只有一辆摆渡车在工作,但摆渡车容量可以视为无限大。摆渡车从人大附中出发、 把车上的同学送到人民大学、再回到人大附中(去接其他同学),这样往返一趟总共花费\(m\)分钟(同学上下车时间忽略不计)。摆渡车要将所有同学都送到人民大学。

    凯凯很好奇,如果他能任意安排摆渡车出发的时间,那么这些同学的等车时间之和最小为多少呢?

    注意:摆渡车回到人大附中后可以即刻出发。

    数据范围:
    \(n \leq 500,m \leq 100,t_i \leq 4 \times 10^6\)

    题解:

    有一个显而易见的事情,如果第\(i\)个人到达了这里,那么在保证最优的情况下他一定是在\([t_i,t_i + m)\)乘车去人大的。

    那么我们就可以得到一个dp,设\(f[i][j]\)表示第\(i\)个人在\([t_i,t_i + j)\)出发的等待时间总和最小值。

    转移暴力枚举即可。

    适当的用前缀和优化一下转移方程即可AC。

    #include <bits/stdc++.h>
    #include <climits>
    using namespace std;
    #define INF 0x3f3f3f3f
    #define rep(i,_,__) for(int i = _;i <= __; ++i)
    const int MAXN = 1010;
    typedef pair<int,int> P;
    #define mk(x,y) make_pair(x,y)
    #define fir first
    #define sec second
    P range[MAXN];
    int read () {
        int q=0,f=1;char ch=getchar();
        while(!isdigit(ch)){
            if(ch=='-')f=-1;ch=getchar();
        }
        while(isdigit(ch)){
            q=q*10+ch-'0';ch=getchar();
        }
        return q*f;
    }
    int f[MAXN][MAXN];
    int t[MAXN];
    int ans;
    int sum[MAXN];
    int n,m;
    int main () {
        n = read(),m = read();
        rep(i,1,n) {
            t[i] = read();
        }
        sort(t + 1,t + n + 1);
       	rep(i,1,n) {
            f[i][0] = INF;
            rep(j,0,min(t[i] - t[i - 1] - m,m - 1)) {
                f[i][0] = min(f[i][0],f[i - 1][j]);
            }
            rep(j,1,(m << 1) - 1) {
                if(t[i] - t[i - 1] + j - m >= 0 and t[i] - t[i - 1] + j - m < (m << 1)) {
                    f[i][j] = min(f[i][j - 1],f[i - 1][t[i] - t[i - 1] + j - m]);
                }
                else {
                    f[i][j] = min(f[i][j - 1],INF);
                }
            }
            rep(j,0,(m << 1) - 1) {
                if(t[i] - t[i - 1] + j < (m << 1)) {
                    f[i][j] = min(f[i][j],f[i - 1][t[i] - t[i - 1] + j]) + j;
                }
                else {
                    f[i][j] = min(f[i][j],INF) + j;
                }
            }
        }
        ans = INT_MAX;
        rep(i,0,m) {
            ans = min(ans,f[n][i]);
        }
       	printf("%d\n",ans);
        return 0;
    }
    
  • 相关阅读:
    Django shortcut functions
    Android 度量单位
    WPF 资源
    WPF Template
    python 常用库
    python 元类
    android中控制ListView宽度和高度
    layout可以显示,程序调用就出错
    请问在pulltorefreshGridView中的图片设置了大小之后怎么就不显示了呢
    Activity表单传值问题
  • 原文地址:https://www.cnblogs.com/akoasm/p/10121009.html
Copyright © 2011-2022 走看看