• 洛谷5017:摆渡车——题解


    https://www.luogu.org/problem/P5017

    参考:https://www.luogu.org/blog/ztyluogucpp/solution-p5017

    我想我大概是废了。

    肯定是要对$t$排序的。

    最初想法肯定是$f[i]$表示前$i$个人全上车或到站的最小等待时间。

    但你能够发现如果不给出上一班车的时间的话$f$根本转移不了。

    那就$f[i][j]$表示最后一班车$j$时开出的最小等待时间?

    数据范围打人脸,于是我就去查题解了

    但是我们发现实际上最后一班车开出的时间一定在$[t[i],t[i]+m)$之间,因为最差上一班车会在$t[i]-1$开出,$t[i]+m-1$回来,如果我们让车停在那里再开出显然会让乘客白等。

    因此我们就可以改变$f[i][j]$为前$i$个人全上车或到站,最后一班车从$t[i]+j$时开出的最小等待时间。

    状态转移方程可以很容易的写出:

    $f[i][j]=min(f[i][j],f[k][l]+sum(k+1,i,t[i]+j))$(你得保证变量合法)

    最终答案就是$min(f[n][0]sim f[n][m-1])$

    其中$sum(i,j,k)$函数表示第$i$人到第$j$人等时刻$k$发车的等待时间和,显然预处理前缀和就可以$O(1)$算了。

    但是这个式子也是$O(n^2m^2)$过不了怎么办?

    我们$j$的下限肯定是$max(t[k]+l+m-t[i],0)$的,但是真的有必要从这个下限枚举到$m-1$吗?

    显然,到$i$上车时,比起让车等着,不如能早发就早发,所以虽然下限往上的状态$f$可能会错,但答案一定不会错。

    因此没必要枚举$j$,复杂度$O(n^2m)$

    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int N=505;
    const int M=105;
    const ll INF=1e18;
    inline int read(){
        int X=0,w=0;char ch=0;
        while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
        while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
        return w?-X:X;
    }
    ll t[N],s[N],f[N][M];
    ll sum(int l,int r,ll now){
        return now*(r-l+1)-s[r]+s[l-1];
    }
    int main(){
        int n=read(),m=read();
        for(int i=1;i<=n;i++)t[i]=read();
        sort(t+1,t+n+1);
        for(int i=1;i<=n;i++)s[i]=s[i-1]+t[i];
        for(int i=1;i<=n;i++){
            for(int j=0;j<m;j++)f[i][j]=sum(1,i,t[i]+j);
            for(int j=1;j<i;j++){
                for(int k=0;k<m;k++){
                    ll now=max(t[j]+k+m,t[i]);
                    f[i][now-t[i]]=min(f[i][now-t[i]],f[j][k]+sum(j+1,i,now));
                }
            }
        }
        ll ans=INF;
        for(int i=0;i<m;i++)ans=min(ans,f[n][i]);
        printf("%lld
    ",ans);
        return 0;
    }

    +++++++++++++++++++++++++++++++++++++++++++

     +本文作者:luyouqi233。               +

     +欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

    +++++++++++++++++++++++++++++++++++++++++++

  • 相关阅读:
    linux MySQL安装指南
    Ubuntu MySQL常用命令
    linux下 mysql 忘记root用户密码解决办法
    ubuntu mysql 启动命令/配置my.cnf
    Ubuntu中给mysql添加新用户并分配权限
    各种 ADSL Modem 及路由器的端口映射方法
    (转)有关SharePoint页面定制的若干细节
    获取Excel中的Sheet的名称
    获取excel表单中的数据
    如何用Excel 2007同步MOSS列表(转)
  • 原文地址:https://www.cnblogs.com/luyouqi233/p/11365405.html
Copyright © 2020-2023  润新知