励志上岸东北大学的狗头吧


私信TA

用户名:uq_67546971622

访问量:437

签 名:

等  级
排  名 10202
经  验 1103
参赛次数 0
文章发表 4
年  龄 0
在职情况 学生
学  校
专  业

  自我简介:

解题思路:

    确定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 人评分

  评论区

  • «
  • »