1 条题解

  • 0
    @ 2025-4-20 13:00:14

    算法标签

    动态规划、最优决策选择动态规划、最优决策选择

    解题思路

    题意分析

    题目描述了一个关于车辆运送的场景。已知有nn个停车场(可理解为一次能运送的车辆数量上限),每辆车从出发到返回的时间间隔为tt(包含去程和回程时间),总共有mm辆车需要运送,并且给出了每辆车的到达时间序列f[i]f[i]ii11mm)。目标是确定最后一辆车被送到的最早时间以及在送完最后一辆车时总共运送的次数。在运送车辆的过程中,每次运送的车辆数量不能超过nn,且要根据车辆的到达时间合理安排运送计划,以达到最后一辆车最早送达的目的。

    解题思路

    1. 数据初始化与输入处理
      • 定义了一些常量,如maxn表示数组的最大长度,inf表示一个很大的数用于初始化最小值。
      • 定义了三个数组dp[i]表示第ii辆车被送到的最早时间,si[i]表示第ii辆车被送到时已经送过的次数,f[i]用于存储每辆车的到达时间。
      • 输入测试用例的数量TT,对于每个测试用例,输入停车场数量nn、每辆车往返时间tt、车辆总数mm,以及每辆车的到达时间f[i]f[i]
    2. 动态规划计算
      • 外层循环遍历每一辆车(从第11辆车到第mm辆车)。
      • 对于每一辆车ii,通过内层循环从i1i - 1max(0,in)\max(0, i - n)来寻找之前的某一次运送,使得当前车ii能最早被送达。这里寻找的依据是比较之前各次运送完成的时间dp[j]jj为之前的某次运送),找到最小的dp[j]对应的jj值(设为mj)。
      • 如果mj小于等于00,则将mj设为11
      • 计算第ii辆车被送到的最早时间dp[i],其值为max(dp[mj1],f[i])+t×2\max(dp[mj - 1], f[i]) + t \times 2。这里的max(dp[mj1],f[i])\max(dp[mj - 1], f[i])表示要等之前的运送完成以及当前车到达,然后再加上往返时间t×2t \times 2
      • 计算第ii辆车被送到时已经送过的次数si[i],其值为si[mj - 1] + 1,即在上一次运送次数的基础上加11
    3. 结果输出
      • 最后输出第mm辆车被送到的最早时间(dp[m] - t,减去tt是因为dp[m]包含了最后一次的往返时间,这里只需要到达时间)以及送完第mm辆车时总共运送的次数si[m]
    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    using namespace std;
    const int maxn=100000;
    const int inf=10000000;
    int dp[maxn];///第i辆车被送到的最早时间
    int si[maxn];///第i辆车被送到时已经送过的次数
    int f[maxn];
    int main() {
        int T; cin>>T;
        while(T--) {
            int n,t,m; cin>>n>>t>>m;
            for(int i=1; i<=m; ++i)cin>>f[i];
            for(int i=1;i<=m;++i){
                int min=inf,mj;
                for(int j=i-1;j>=0&&j>i-n;--j)
                    if(dp[j]<=min)
                        min=dp[j],mj=j;
                if(mj<=0) mj=1;
                dp[i]=max(dp[mj-1],f[i])+t*2;
                si[i]=si[mj-1]+1;
            }
            cout<<dp[m]-t<<' '<<si[m]<<endl;
        }
        return 0;
    }
    • 1

    信息

    ID
    1337
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者