POJ - 1661 : Help Jimmy
思路
- DP(动态规划)问题
- 垂直方向所走的路径一定,所以只用记录水平方向
- 每次的选择只有两个:向左走 和 向右走
- DFS 遍历所有可能解,用path数组记录每个平台从左走和从右走的路径最小值
代码
#include<stdio.h>
#include<limits.h>
#include<algorithm>
#include<string.h>
using namespace std;
int t,N,X,Y,MAX;
int result,start;
int path[1000][2];
struct Node{
int x;
int y;
int h;
};
Node G[1000];
bool compare(Node x,Node y){
return x.h > y.h;
}
int dfs(int x,int h,int begin){
int i,length1,length2;
bool flag=0;
for(i=begin+1;i<N;i++){
if(G[i].h+MAX<h){
i = N;
break;
}
if(G[i].x<=x&&G[i].y>=x){
flag = 1;
break;
}
}
if(i<N){
if(!path[i][0]){
path[i][0] = dfs(G[i].x,G[i].h,i);
if(path[i][0]==-1){
length1 = -1;
}else{
length1 = (x - G[i].x) + path[i][0];
}
}else{
if(path[i][0]==-1){
length1 = -1;
}else{
length1 = (x - G[i].x) + path[i][0];
}
}
if(!path[i][1]){
path[i][1] = dfs(G[i].y,G[i].h,i);
if(path[i][1]==-1){
length2 = -1;
}else{
length2 = (G[i].y - x) + path[i][1];
}
}else{
if(path[i][1]==-1){
length2 = -1;
}else{
length2 = (G[i].y - x) + path[i][1];
}
}
if(length1!=-1&&length2!=-1){
return min(length1,length2);
}else if(length1==-1&&length2==-1){
return -1;
}else{
return length1==-1?length2:length1;
}
}
if(!flag&&h<=MAX){
return 0;
}else{
return -1;
}
}
int main(){
scanf("%d",&t);
for(int a=0;a<t;a++){
memset(path,0,sizeof(path));
scanf("%d %d %d %d",&N,&X,&Y,&MAX);
for(int b=0;b<N;b++){
scanf("%d %d %d",&G[b].x,&G[b].y,&G[b].h);
}
sort(G,G+N,compare);
result = dfs(X,Y,-1);
printf("%d\n",result+Y);
}
}