1 条题解

  • 0
    @ 2025-8-24 21:25:47

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar yyy2015c01
    未来道具研究所

    搬运于2025-08-24 21:25:46,当前版本为作者最后更新于2016-08-22 17:15:55,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    #具体看注释!!!

    #具体看注释!!!

    #具体看注释!!!

    ###步骤:

    **1. 看代码

    1. 看代码

    2. 看代码**

    //不加注释的题解都是流氓
    #include<iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <ctime>
    #include <cctype>
    #include <climits>
    #include <algorithm>
    #include <map>
    #include <queue>
    #include <vector>
    #include <string>
    #include <cstring>
    #include <sstream>
    #include <fstream>
    using namespace std;
    const int INF=66666666;
    struct node {
        int start,end;//start:出发时刻,end:到达时刻
    } car[305][305];//car[i][j]:从i关口出发的第j辆车
    int n,m;
    int dp[55][33000]={0};//dp[i][j]:到达第i个关口耗时j秒遇到巡逻车的最小次数
    int num[305]={0};//num[i]:从第i个关口出发的巡逻车数
    int change(int time)//传入hhmmss格式的时间,返回从6点开始到这个时刻的秒数
    {
        int h,m,s;
        h=time/10000;
        time-=h*10000;
        h-=6;
        m=time/100;
        time-=m*100;
        s=time;
        return (h*3600+m*60+s);
    }
    int changeBack(int T)//传入6点开始到现在的秒数,返回hhmmss格式的时间数字(不含前导0)
    {
        int h,m,s;
        h=T/3600;
        T-=h*3600;
        h+=6;
        m=T/60;
        T-=m*60;
        s=T;
        return h*10000+m*100+s;
    }
    int main()
    {
        freopen("patrol.in","r",stdin);
        freopen("patrol.out","w",stdout);
        scanf("%d %d",&n,&m);
        int n600=n*600;
        int ni,Ti,ti;
        memset(dp,50,sizeof(dp));
        for(int i=0; i<m; i++) {
            scanf("%d %d %d",&ni,&Ti,&ti);
            ni--;//因为数组从0开始
            Ti=change(Ti);
            car[ni][num[ni]].start=Ti;
            car[ni][num[ni]].end=ti+Ti;
            num[ni]++;
        }
        dp[0][0]=0;
        n--;//因数组从0开始
        bool b=false;
        for(int i=0; i<n; i++) {//枚举关口
            for(int j=i*300,i600=i*600; j<=i600; j++) {//枚举总耗时
                for(int k=300; k<=600; k++) {//枚举当前关口耗时
                    int times=0,jk=j+k;
                    for(int p=0; p<num[i]; p++) {
                        if((car[i][p].start>=j&&car[i][p].end>jk)||(car[i][p].start<=j&&car[i][p].end<jk))
                            continue;//没有超车
                        else
                            times++;//超车或同时到达
                    }
                    dp[i+1][jk]=min(dp[i+1][jk],dp[i][j]+times);//dp方程
                    if (dp[i+1][jk]==0) {//优化:dp[i][j]=0,则dp[i][k](k>j)皆为0.
                        for (int p=jk+1,i602=i600+600;p<=i602;p++) {
                            dp[i+1][p]=0;
                        }    
                        b=true;
                        break;
                    }
                }
                if (b) break;
            }
            if (b) {
                b=false;
                continue;
            }
        }
        int result=INF;
        int minTime;
        for(int i=n*300,n601=n600-600; i<=n601; i++) {//找最少的
            if(result>dp[n][i]) {
                result=dp[n][i];
                minTime=i;
            }
        }
        int printTime=changeBack(minTime);
        printf("%d\n",result);
        if (printTime<100000) printf("0");//补前导0
        printf("%d\n",printTime);
        return 0;
    }
    
    • 1

    信息

    ID
    492
    时间
    1000ms
    内存
    125MiB
    难度
    4
    标签
    递交数
    0
    已通过
    0
    上传者