典型的记忆化搜索问题,dfs一遍即可。但是不知道WA在哪里了= =,一直都没找出错误。因为思路是很简单的,肯定是哪里写挫了,因此不再继续追究了。
WA的代码如下,希望日后有一天能找出错误= =:
————————————————灵光一闪的分界线——————————————————
在写博客的时候突然灵光一闪,想到了错在哪里了= =。总的来说还是考虑问题不周导致的。AC代码如下:
1 #include <stdio.h> 2 #include <algorithm> 3 #include <string.h> 4 using namespace std; 5 const int N = 1000 + 5; 6 const int inf = 0x3f3f3f3f; 7 8 int n,x,y,limit; 9 int left[N],right[N],h[N]; 10 int L_nxt[N],R_nxt[N]; 11 void find(int u) 12 { 13 int L = -1, R = -1; 14 for(int i=1;i<=n;i++) 15 { 16 if(u == i || h[i] >= h[u]) continue; 17 if(left[u] >= left[i] && left[u] <= right[i]) 18 { 19 if(L == -1) L = i; 20 else if(h[i] > h[L]) L = i; 21 } 22 if(right[u] >= left[i] && right[u] <= right[i]) 23 { 24 if(R == -1) R = i; 25 else if(h[i] > h[R]) R = i; 26 } 27 } 28 if(L == -1) 29 { 30 if(h[u] > limit) L_nxt[u] = -2; // 表示不能往这个方向跳下 31 else L_nxt[u] = -1; // 表示可以到地面 32 } 33 else if(h[u] - h[L] > limit) L_nxt[u] = -2; 34 else L_nxt[u] = L; 35 36 if(R == -1) 37 { 38 if(h[u] > limit) R_nxt[u] = -2; // 表示不能往这个方向跳下 39 else R_nxt[u] = -1; // 表示可以到地面 40 } 41 else if(h[u] - h[R] > limit) R_nxt[u] = -2; 42 else R_nxt[u] = R; 43 } 44 45 struct node 46 { 47 int L, R; 48 void init() {L = R = inf;} 49 }; 50 bool vis[N]; 51 node dp[N]; 52 node dfs(int u) 53 { 54 if(vis[u]) return dp[u]; 55 vis[u] = 1; 56 node ans; ans.init(); 57 if(L_nxt[u] != -2) 58 { 59 if(L_nxt[u] == -1) ans.L = h[u]; 60 else 61 { 62 node temp = dfs(L_nxt[u]); 63 ans.L = min(ans.L, h[u] - h[L_nxt[u]] + min(left[u] - left[L_nxt[u]] + temp.L, right[L_nxt[u]] - left[u] + temp.R)); 64 } 65 } 66 67 if(R_nxt[u] != -2) 68 { 69 if(R_nxt[u] == -1) ans.R = h[u]; 70 else 71 { 72 node temp = dfs(R_nxt[u]); 73 ans.R = min(ans.R, h[u] - h[R_nxt[u]] + min(right[u] - left[R_nxt[u]] + temp.L, right[R_nxt[u]] - right[u] + temp.R)); 74 } 75 } 76 return dp[u] = ans; 77 } 78 79 int main() 80 { 81 int T; scanf("%d",&T); 82 while(T--) 83 { 84 scanf("%d%d%d%d",&n,&x,&y,&limit); 85 for(int i=1;i<=n;i++) scanf("%d%d%d",left+i,right+i,h+i); 86 for(int i=1;i<=n;i++) find(i); 87 memset(vis,false,sizeof vis); 88 89 int root = -1; 90 for(int i=1;i<=n;i++) 91 { 92 if(x >= left[i] && x <= right[i]) 93 { 94 if(root == -1) root = i; 95 else if(h[root] < h[i]) root = i; 96 } 97 } 98 // root为-1的话dfs会出错的,因此要特判 99 if(root == -1) {printf("%d\n",y); continue;} 100 101 dfs(root); 102 int ans = y - h[root] + min(x - left[root] + dp[root].L, right[root] - x + dp[root].R); 103 printf("%d\n",ans); 104 } 105 return 0; 106 }