Description
一条船能够一次最多渡n辆车过河,过河用t分钟,回来又要用t分钟。m辆车按照一定的计划到达岸边。现在要求最少用多少时间将所有的船渡过河,以及最少用多少次来将所有的车渡过河。
Input
第一行是测试数据的组数,每组测试数据第一行有n,t,m;接下来是m行,每一行给出每辆车到达的时间。注意船只能去渡已经到达岸边的车。0<n,t,m<1440
Output
每组测试数据一行两个整数,第一个是用的最少的时间,第二个是用的最少的次数。
Sample Input
2
2 10 10
0
10
20
30
40
50
60
70
80
90
2 10 3
10
30
40
Sample Output
100 5
50 2
思路引导
用贪心思想,最早运到对岸的时间,取决于最后来到一辆车的被运送时间。因此最优解即是最后一辆车能够最早被运送。
解题报告
本题的最优解就是保证最后一辆车能够最早被运送到。假设有11辆车且船一次最多可以载5辆车,这样的问题可以转化为前面6辆车的最早运送,并且船只回来的时间和最后一辆车到达原岸的时间中较晚者作为最后五辆车的出发时刻。这样就可以转化为求前6辆的最优解,规模缩小。这样解法为,如果m%n==0,则每次都运送n辆车;否则第一次运送m%n辆,以后每次都运送n辆车。
#include<stdio.h>
#include<stdlib.h>
void SolveGreedy(int n,int t,int m)
{
int i,j;
int l = m%n;
int k = m/n;
int time_now; //当前船只来到原岸的时间
int time_return = 0;//前一组运送渡船的返回时间
int trans_times = k;
if(l)
{
trans_times++;
for(i=0;i<l;i++)
scanf(“%d”,&time_now);
time_return = time_now+2*t;
}
for(i=0;i<k;i++)
{
for(j=0;j<n;j++)
scanf(“%d”,&time_now);
if(time_now<=time_return)
time_return = time_return+2*t;
else
time_return = time_now+2*t;
}
printf(“%d %d”,time_return-t,trans_times);
}
int main()
{
int testNum;
int n,t,m;
scanf(“%d”,&testNum);
while(testNum–)
{
scanf(“%d %d %d”,&n,&t,&m);
SolveGreedy(n,t,m);
}
return 0;
}