题目解析
所以任何车辆都不能超车
就是简单地求出所有车怎么分组,不用考虑排序
任何一组车队的重量之和不能超过桥的最大承重量
这就是边界条件,用来判断是否在某个子问题中继续规划下去
一组车队通过该桥的时间是用该车队中速度最慢的车通过该桥所需的时间来表示的
从这句话我们知道选取的车应该是在某一子问题中满足重量要求的所花时间的最大值
思路
——–*(01背包问题)*———-
f[i]表示过前i辆车时需要的最少时间
状态转移方程:f[i]=min(f[i],f[first-1]+time);
first表示最后一组的第一辆车
f[first-1]就是除最后一组的前几组的最少时间
time表示最后一组的时间
代码
`int n;//车辆数
int maxn;//桥的最大载重量
int f[];
int max;//用来记录目前达到的最大的重量,这个值不能超过maxn,也就是桥的最大载重量
inline void dp(){
for(int i=1;i<=n;++i){
max=0,time=0;//不断更新
for(int j=i;j>=1;--j){
max+=time1/*(就是这辆车的时间)*/;
if(max>maxn)break;
time=max(time,time1);//详见题目解析
f[i]=min(f[i],f[j-1]+time);//递推式:前i-1辆车的最短时间 和第i辆车的的时间和最短的那个
}
}
}`
后续的几个问题
修了好几遍
数据类型必须是long long
max()
和min()
的返回值必须是double
型的不然会诡异爆数字
比如说:
`inline double min(double a,double b){
return a<b?a:b;
}
inline double max(double a,double b){
return a>b?a:b;
}`
f[]数组一开始就必须是小数,不然输出比较麻烦。。。也就是f[0]=0.0
代码终极版
`#include<cstdio>
#include<cstring>
using namespace std;
const int N=1005;
double t1=0;
long long t2=0;
struct car{
int w;
double t;
};
int wmax,l,n;
car c[N];
double f[N];
inline double min(double a,double b){
return a<b?a:b;
}
inline double max(double a,double b){
return a>b?a:b;
}
inline void output();
inline void dp();
inline void dp_ready();
inline void input();
int main()
{
input();
dp_ready();
dp();
output();
return 0;
}
inline void input(){
scanf("%d %d %d",&wmax,&l,&n);
for(int i=1;i<=n;++i)
{
scanf("%d%lf",&c[i].w,&c[i].t);
c[i].t=(double)l/c[i].t;
}
}
inline void dp_ready(){
memset(f,127,sizeof(f));
f[0]=0.0;
}
inline void dp(){
for(int i=1;i<=n;++i)
{
t1=0,t2=0;
for(int j=i;j>=1;--j)
{
t2+=c[j].w;
if(t2>wmax) break;
t1=max(t1,c[j].t);
f[i]=min(f[i],f[j-1]+t1);
}
}
}
inline void output(){
printf("%.1lf",f[n]*60);
}`
### ***THE END***