蓝桥杯 蜗牛 动态规划

16.蜗牛 - 蓝桥云课https://www.lanqiao.cn/problems/4985/learning/?page=1&first_category_id=1&second_category_id=3&sort=difficulty&asc=1&tags=%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92,%E9%80%92%E6%8E%A8,01%E8%83%8C%E5%8C%85,%E5%8C%BA%E9%97%B4DP,%E6%95%B0%E4%BD%8DDP,%E6%96%9C%E7%8E%87%E4%BC%98%E5%8C%96,%E6%9C%9F%E6%9C%9BDP,%E6%A0%91%E5%BD%A2DP,%E7%8A%B6%E5%8E%8BDP,%E8%83%8C%E5%8C%85%E9%97%AE%E9%A2%98,%E8%AE%B0%E5%BF%86%E5%8C%96%E6%90%9C%E7%B4%A2&tag_relation=union

一道DP题

要求求出从原点开始到第N根柱子(竹竿)的底部的最短时间

所以我们要设置一个DP数组 dp[i]表示到第i根柱子底部的最短时间

以到第三根柱子底部的最短时间为例子

我们发现有两种方法可以到达第三根柱子的底部

第一种,从出发点1 开始走第二根柱子的传送门,传送到第三根柱子的相应位置pre然后从pre走到第三根柱子底部;

第二种,从第二根柱子的底部直接过来第三根柱子的底部 ;

考虑第一种方法的原因在于 如果两根柱子离得非常远 比如距离为10000,而走传送门在柱子上移动的距离只有10,远小于直接走X轴

考虑第二种方法的原因在于 有可能两柱子离得非常近 比如在x轴的距离为1 ,传送门却非常高,比如传送门高度10000;因此直接从底下走过去更快

因此实际上我们需要计算出到第i根柱子的底部的最短时间,实际上需要到第i-1根柱子的传送门的最短时间,和到第i-1根柱子底部的最短时间两个数据

分别记作dp[i-1][0],dp[i-1][1]

复制代码
#include<bits/stdc++.h>
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1e5+10;
typedef long long ll; 
int n;
struct node{
	double cur;
	double nxt;
	double pre;
	double x;
};
double dp[N][2]; 
node a[N];

int main(){
	cin>>n;
	for(int i = 1 ; i<=n;i++){
		cin>>a[i].x ;
	}
	for(int i = 1;i<n;i++){
		cin>>a[i].cur ;  //当前柱子的传送门位置 
		cin>>a[i].nxt ; //传送到下一根柱子的位置 
		a[i].pre = a[i-1].nxt ; //被上一根柱子传送过来的出口 
	}

	
	a[0].x   = 0;
	a[0].cur = 0;
	
	a[n].cur = a[n-1].nxt ;
	a[n].pre = a[n-1].nxt ;
	
	dp[0][1] = 0;
	dp[0][0] = 1e8;
	
	for(int i = 1 ; i <= n;i++)
	{
		double add1 ; //上个传送门传过来 再走到当前传送门 
		//传送门有可能在上一个柱子出口的上面 也可能在出口的下面 
		if(a[i].cur > a[i].pre ){
			add1 = (a[i].cur - a[i].pre)/((0.7)*1.0) ;  
		}else if(a[i].cur <= a[i].pre ){
			add1 = (a[i].pre - a[i].cur)/((1.3)*1.0) ; 
		}
		
		double timecur1 = dp[i-1][0] + add1;   
		///到上个柱子传送门的最短时间 +  被传送出来后走到当前柱子传送门的时间 
		

		double line11 = dp[i-1][1];                
		double line12 = a[i].x - a[i-1].x ;       //右 
		double line13 = a[i].cur /((0.7)*1.0);    //上 
		double timecur2 = line11 + line12 +line13 ;
		/// 在上个柱子底部的最短时间  + 走到第i根柱子再上传送门 
		dp[i][0] = min(timecur1,timecur2); //到当前柱子传送门最短时间 
		
		double timedown1 = dp[i-1][1] + a[i].x - a[i-1].x; //从上个柱子底直接走到这个柱子底部 
	
		double line22 = a[i].pre/((1.3)*1.0); //从传送门下到柱子底部 
		double timedown2 = dp[i-1][0]   + line22;
		
		dp[i][1] = min(timedown1,timedown2);//到当前柱子底最短时间 
	}

	
	printf("%.2lf",dp[n][1]);

	return 0;
}
相关推荐
山,离天三尺三7 小时前
线程中互斥锁和读写锁相关区别应用示例
linux·c语言·开发语言·面试·职场和发展
代码充电宝16 小时前
LeetCode 算法题【简单】283. 移动零
java·算法·leetcode·职场和发展
Excuse_lighttime1 天前
除自身以外数组的乘积
java·数据结构·算法·leetcode·eclipse·动态规划
liuyao_xianhui1 天前
四数之和_优选算法(C++)双指针法总结
java·开发语言·c++·算法·leetcode·职场和发展
墨染点香1 天前
LeetCode 刷题【93. 复原 IP 地址】
算法·leetcode·职场和发展
Asmalin1 天前
【代码随想录day 29】 力扣 860.柠檬水找零
算法·leetcode·职场和发展
程序员小白条1 天前
度小满运维开发一面
java·运维·python·职场和发展·运维开发
Asmalin2 天前
【代码随想录day 29】 力扣 135.分发糖果
算法·leetcode·职场和发展
微笑尅乐2 天前
多解法详解与边界处理——力扣7.整数反转
算法·leetcode·职场和发展
덕화2 天前
模拟面试 - 第6轮
面试·职场和发展