题目描述
现有N辆车要按顺序通过一个单向的小桥,由于小桥太窄,不能有两辆车并排通过。另外,由于小桥建造的时间已经很久,只能承受有限的重量,记为Max(吨)。管理员将N辆车按初始的顺序分组,每次让一个组过桥,并且只有在一个组的车辆全部过桥后,下一组车辆才能上桥。每辆车的重量和最大速度是已知的,而每组车的过桥时间由该组中速度最慢的那辆车决定。请你帮管理员编一个程序,将这N辆车分组,使得全部车辆通过小桥的时间最短。
输入格式
第一行有3个数字,分别为Max(吨),Len(桥的长度,单位km),N(3个数之间用一个或多个空格隔开)。
接下来又N行,每行两个数,第i行的两个数分别表示第i辆车的重量w(吨)和最大速度v(km/h)。
max,len,w,v不超过32位有符号整数类型的最大值,且为整数n<1000
输出格式
全部车辆通过小桥的最短时间(minute),精确到小数点后一位。
样例
样例输入
100 4 10
40 25
50 20
50 20
70 10
12 50
9 70
49 30
38 25
27 50
19 70
样例输出
60.0
Solution
题目要求按照初始的顺序分组,所以必须按照
1
~
n
1\sim n
1~n 的顺序过桥,所以设
f
[
i
]
f[i]
f[i] 表示从
1
1
1 到
i
i
i 需要花费的最小时间,则可以先预处理出每一组车
[
i
,
j
]
[i,j]
[i,j] 在不考虑重量限制的情况下的通过时间
g
[
i
,
j
]
g[i,j]
g[i,j],则状态转移方程为:
g
[
i
,
j
]
=
m
a
x
(
g
[
i
,
j
?
1
]
,
g
[
j
,
j
]
)
f
[
i
]
=
min
?
1
≤
?
j
?
≤
?
i
{
f
[
j
?
1
]
+
g
[
j
]
[
i
]
}
\begin{matrix} g[i,j]=max(g[i,j-1],g[j,j])\\\\ f[i]=\min\limits_{_{1\le\ j\ \le\ i}}\left\{ f[j-1]+g[j][i]\right\} \end{matrix}
g[i,j]=max(g[i,j?1],g[j,j])f[i]=1≤?j?≤?i?min?{f[j?1]+g[j][i]}?
初值:
f
[
i
]
=
I
N
F
,
g
[
i
,
i
]
=
T
i
m
e
(
i
)
f[i]=\mathrm{INF},g[i,i]=Time(i)
f[i]=INF,g[i,i]=Time(i) 目标:
f
[
n
]
f[n]
f[n]
AC Code
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int N=1005;
int m,n;
int s[N];
double g[N][N],f[N],l,v;
int main()
{
scanf("%d%lf%d",&m,&l,&n);
for(register int i=1;i<=n;i++)
{
scanf("%d%lf",&s[i],&g[i][i]);
s[i]+=s[i-1];g[i][i]=(l/g[i][i])*60;
}
for(register int i=1;i<=n;i++)
{
for(register int j=i+1;j<=n;j++)
g[i][j]=max(g[i][j-1],g[j][j]);
}
for(register int i=1;i<=n;i++)
{
f[i]=1e9;
for(register int j=1;j<=i;j++)
if(s[i]-s[j-1]<=m) f[i]=min(f[i],f[j-1]+g[j][i]);
}
printf("%.1lf\n",f[n]);
return 0;
}
|