[POJ2336]Ferry Loading II

题目描述 Description

Before bridges were common, ferries were used to transport cars across rivers. River ferries, unlike their larger cousins, run on a guide line and are powered by the river's current. Cars drive onto the ferry from one end, the ferry crosses the river, and the cars exit from the other end of the ferry. 
There is a ferry across the river that can take n cars across the river in t minutes and return in t minutes. m cars arrive at the ferry terminal by a given schedule. What is the earliest time that all the cars can be transported across the river? What is the minimum number of trips that the operator must make to deliver all cars by that time?

输入描述 Input Description

The first line of input contains c, the number of test cases. Each test case begins with n, t, m. m lines follow, each giving the arrival time for a car (in minutes since the beginning of the day). The operator can run the ferry whenever he or she wishes, but can take only the cars that have arrived up to that time.

输出描述 Output Description

For each test case, output a single line with two integers: the time, in minutes since the beginning of the day, when the last car is delivered to the other side of the river, and the minimum number of trips made by the ferry to carry the cars within that time. 

You may assume that 0 < n, t, m < 1440. The arrival times for each test case are in non-decreasing order.

样例输入 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

数据范围及提示 Data Size & Hint

 

之前的一些废话:近日诸事不顺。

题解:首先把题目大意说一下:一个轮船它可以承载n辆车,它要把m辆车送到对岸,从此岸到彼岸需要的时间为t,给出m辆车的到达此岸的时间,问要把所有m辆车送到对岸需要最短的时间为多少?在最短的时间内最少可以多少趟完成任务。

dp(i)表示运完第i条船所需时间。从j=(i-n,i-1)转移而来,表示枚举每次运的辆数,dp[i]=max(a[i],dp[j])+2*t 转移过程中顺便完成对趟数的处理。

代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
#define mem(a,b) memset(a,b,sizeof(a))
inline int read()
{
    int x=0,f=1;char c=getchar();
    while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
    while(isdigit(c)){x=x*10+c-'0';c=getchar();}
    return x*f;
}
const int maxn=1450,oo=2147483647;
int T,n,m,t,a[maxn],ans,ans1,dp[maxn],cnt[maxn];
int main()
{
    T=read();
    while(T--)
    {
        mem(dp,42);mem(cnt,42);ans1=ans=oo;
        n=read();t=read();m=read(); 
        for(int i=1;i<=m;i++)a[i]=read();
        dp[0]=0;cnt[0]=0; 
        for(int i=1;i<=m;i++) 
              for(int j=max(0,i-n);j<i;j++)
            {
                if(dp[i]>max(a[i],dp[j])+2*t)
                {
                    dp[i]=max(a[i],dp[j])+2*t;
                    cnt[i]=cnt[j]+1;
                }
                else if(dp[i]==max(a[i]-dp[j],0)+2*t)cnt[i]=min(cnt[i],cnt[j]+1);
            }
        for(int i=max(0,m-n);i<m;i++)ans=min(ans,max(dp[i],a[m])+t);
        for(int i=max(0,m-n);i<m;i++)ans1=min(ans1,cnt[i]+1);
        printf("%d %d\n",ans,ans1);
    }
    return 0;
}
View Code

总结:

posted @ 2017-07-08 15:27  小飞淙的云端  阅读(197)  评论(0编辑  收藏  举报