#2306. NOIP2018 普及组 第三题 摆渡车
NOIP2018 普及组 第三题 摆渡车
Description
有n名同学要乘坐摆渡车从人大附中前往人民大学,第i位同学在第ti分钟去 等车。只有一辆摆渡车在工作,但摆渡车容量可以视为无限大。摆渡车从人大附中出发、 把车上的同学送到人民大学、再回到人大附中(去接其他同学),这样往返一趟总共花费m分钟(同学上下车时间忽略不计)。
摆渡车要将所有同学都送到人民大学。
凯凯很好奇,如果他能任意安排摆渡车出发的时间,那么这些同学的等车时间之和最小为多少呢?
注意:摆渡车回到人大附中后可以即刻出发。
Input Format
第一行包含两个正整数n,m,以一个空格分开,分别代表等车人数和摆渡车往返一趟的时间第二行包含n个正整数,相邻两数之间以一个空格隔开,第i个非负整数ti代表第i个学生到达车站的时刻
Output Format
输出一行,一个整数,表示所有同学等车时间之和的最小值(单位:分钟)。【输入输出样例 1】
5 1
3 4 4 3 5
【输入输出样例 2】
5 5
11 13 1 5 5
【输入输出样例 1】
0
【输入输出样例 2】
4
Hint
对于100%的数据,n<=500,m<=100,0<=ti<=4*10^6;
设f[i][j]代表前i个同学,第i个同学在第t[i]+j分钟到达的最小等待时间总和,这样的状态就不会出错。其实,这样设置后我们可以很简单地划分阶段,f[i][j]不需要从f[k][l]转移,只需要从f[i−1][k]转移即可,因为i个同学必然属于以下两类中的一类:
1.第i个同学和第i−1个同学坐同一辆车
2.第i个同学和第i−1个同学不坐同一辆车
那么我们来讨论转移的细节。
先看一个最基本的问题,两位到达时间差超过m且到达时间相邻的同学必然不坐同一辆车,因为他们的时间间隔足以让车往返一趟。
那么状态第二维的上限只需要开到2m大小即可,达到上限的情况就是和他同时来的一个同学直接坐车走了,花费m分钟,车回来后再送他,又花费m分钟,在第t[i]+2m分钟时,前i位同学全部到达。
此时,我们利用阶段转移:
1. if(t[i−1]+k==t[i]+j) f[i][j]=min(f[i][j],f[i−1][k]+j)
2. if(t[i−1]+k+m<=t[i]+j) f[i][j]=min(f[i][j],f[i−1][k]+j)
初值:
for(int i=1; i<=m*2; i++) f[1][i]=i;
是第1位同学等待的时间。