解题思路:
确定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分
1 人评分
C语言程序设计教程(第三版)课后习题8.1 (C语言代码)浏览:774 |
C语言程序设计教程(第三版)课后习题10.2 (C语言代码)浏览:1151 |
C语言程序设计教程(第三版)课后习题8.9 (C语言代码) 用函数传参的方法浏览:4120 |
C语言程序设计教程(第三版)课后习题11.1 (C语言代码)浏览:695 |
C语言程序设计教程(第三版)课后习题10.5 (C语言代码)浏览:1484 |
C语言程序设计教程(第三版)课后习题8.9 (Java代码)浏览:1413 |
最小公倍数 (C语言代码)浏览:894 |
Pascal三角 (C语言代码)浏览:1252 |
C语言训练-大、小写问题 (C语言代码)浏览:792 |
WU-格式化数据输出 (C++代码)浏览:1312 |