#include<iostream> #include<stdio.h> #include<algorithm> #include<cstring> using namespace std; const int N=1010; const int M=20010; const int INF=0x3f3f3f; struct Time { int x1,x2,h; }a[N]; int dp[N+2][2]; // 0:表示第i的木板左边到底部的最短时间 // 1: 表示第i的木板右边到底部的最短时间 int n,x,y,max_h; int cmp(Time c,Time b) //排序函数 { return c.h > b.h; //从大到小排列 } void left(int i)//左 { //如果平台i下面有平台,且两者相距不超过MAX int k = i+1; while( k<n+1 && a[i].h-a[k].h<=max_h ) //n+1处是地面 { //确保平台k在平台i的左下方,且小鼠可以跳到上面 if(a[i].x1>=a[k].x1&&a[i].x1<= a[k].x2) { //从i的左端跳到地面的时间 //i先跳到k的时间+ //min(从k左端跳到地面的时间+从i的左端到k的左端的时间,从k的右端跳到地面的时间+从i左端到k的右端) dp[i][0]=a[i].h-a[k].h+min(dp[k][0]+a[i].x1-a[k].x1,dp[k][1]+a[k].x2-a[i].x1); return; } k++; } //因为第二个条件出的循环即:不能到达下一平台 if(a[i].h-a[k].h>max_h) dp[i][0]=INF; //因为它下面没木板,直接落地 else dp[i][0]=a[i].h; } void right(int i)//右 { //如果平台i下面有平台,且两者相距不超过MAX int k=i+1; while(k<n+1 && a[i].h-a[k].h<=max_h) { //确保平台k在平台i的右下方,且小鼠可以跳到上面 if(a[i].x2<=a[k].x2 && a[i].x2 >= a[k].x1) { dp[i][1]=a[i].h-a[k].h+min(dp[k][0] + a[i].x2-a[k].x1 , dp[k][1] + a[k].x2-a[i].x2); return; } k++; } //不能到达下一平台 if(a[i].h-a[k].h > max_h) dp[i][1]=INF; //因为它下面没木板,直接落地 else dp[i][1]=a[i].h; } int main() { int t,i; cin>>t; while(t--) { //木板个数、老鼠的初始坐标、最大跳跃高度 cin>>n>>x>>y>>max_h; //地面也当做一块木板 a[0].x1=-20000; a[0].x2=20000; a[0].h=0; //老鼠初始位置也当做一块木板 a[1].x1=x; a[1].x2=x; a[1].h=y; //输入数据 for(i=2;i<=n+1;i++) cin>>a[i].x1>>a[i].x2>>a[i].h; //高度从大到小 sort(a,a+n+2,cmp); //初始化 memset(dp,0,sizeof(dp)); //n+1是地面 //所以从n开始 for(i=n; i>=0 ;i--) { //进行左:去bfs left(i); //进行右:去bfs right(i); } cout<<min(dp[0][0],dp[0][1])<<endl; } return 0; }
原文地址:https://www.cnblogs.com/QingyuYYYYY/p/12238564.html
时间: 2024-10-07 16:57:48