[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. |
输入描述 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. |
样例输入 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; }
总结: