解题思路:
确定dp的含义
定义f[i][2],其中f[i][0]表示到达第i个杆子下方所需要的最小时间,f[i][1]表示到达第i个杆子传送门所需要的最少时间。
a[i]表示第i个杆子的传送门的位置
b[i]表示第i-1个传送门传送到第i个杆子的位置
x[i]表示第i个杆子的位置坐标
确定状态转移
第i个杆子的下方,即f[i][0],可以考虑两个方向到达,第一个方向为左侧到达,第二个方向为传送门到达。从左侧到达为f[i][0] = f[i-1][0] + (x[n]-x[n-1])*(1/1.0)。从上方到达则为f[i][0] = f[i-1][1] + b[i-1]*(1/1.3)。取其最小值为f[i][0],即f[i][0] = min( f[i-1][0] + (x[n]-x[n-1])*(1/1.0),f[i-1][1] + b[i-1]*(1/1.3))。第i个杆子传送门位置,即f[i][1],同样需要考虑两个方向到达,第一个方向为下侧到达,第二个方向是第i-1个传送门传送的位置到达。由于传送门的位置不定,因此可能出现在传送位置的上侧也可能出现在传送位置的下侧,由于速度不一,因此需要分开进行考虑。从下侧到达时f[i][1] = f[i][0] + a[i]*(1/0.7)。这里的f[i][0]已经在前面算出。从传送门位置到达为f[i-1][1] + (b[i-1]-a[i])*(1/1.3)或f[i-1][1] + (a[i]-b[i-1])*(1/0.7)具体取决于传送门的位置。取其最小值为f[i][1]。
可得状态转移方程f[i][0] = min( f[i-1][0] + (x[n]-x[n-1])*(1/1.0),f[i-1][1] + b[i-1]*(1/1.3))。
f[i][1] = min( f[i][0] + a[i]*(1/0.7),f[i-1][1] + (b[i-1]-a[i])*(1/1.3)) (传送门在下方的时候)
f[i][1] = min( f[i][0] + a[i]*(1/0.7),f[i-1][1] + (a[i]-b[i-1])*(1/0.7)) (传送门在上方的时候)
注意事项:
1.需要考虑传送门的位置,可以在上方也可以在下方,因为上爬,下滑速度不一。
2.需要使用double类型,float类型会缺失精度。
3.传送门在传送点下方的时候依然可以到达下方,即传送门不一定非要使用。
4.在n=1的时候需要单独进行考虑
参考代码:
#include<iostream>
#include<stdio.h>
using namespace std;
const int MAXSIZE = 100010;
int a[MAXSIZE],b[MAXSIZE];
int x[MAXSIZE];
double f[MAXSIZE][2];//上方最小值和下方最小值
double minfloat(double a,double b){
if(a>b)return b;
else return a;
}
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>x[i];
}
for(int i=1;i<n;i++){
cin>>a[i];
cin>>b[i];
}
f[1][0] = x[1]*1;
f[1][1] = x[1]*1 + a[1]*(1/0.7);
for(int i = 2;i<n;i++){
int dx = x[i] - x[i-1];
if(a[i]-b[i-1] > 0){
f[i][0] = minfloat(f[i-1][0] + (double)dx*(1/1.0),f[i-1][1] + b[i-1]*(1/1.3));
f[i][1] = minfloat(f[i][0] + a[i]*(1/0.7),f[i-1][1] + (a[i]-b[i-1])*(1/0.7));
}else{
f[i][0] = minfloat(f[i-1][0] + (double)dx*(1/1.0),f[i-1][1] + b[i-1]*(1/1.3));
f[i][1] = minfloat(f[i][0] + a[i]*(1/0.7),f[i-1][1] + (b[i-1]-a[i])*(1/1.3));
}
}
double minn;
if(n!=1)
minn = minfloat(f[n-1][0] + (x[n]-x[n-1])*(1/1.0),f[n-1][1] + b[n-1]*(1/1.3));
else
minn = x[1]*(1/1.0);
printf("%0.2lf",minn);
return 0;
}0.0分
2 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复