题目链接:http://poj.org/problem?id=1661
分析:类似于最长递增子序列的dp题;坑点:如果下落过程中碰到板,那么必须在改板向左右再下落,不可以穿板,所以找到一次,该方向(左或者右)就不需要再找了
1 #include<iostream>
2 #include<sstream>
3 #include<cstdio>
4 #include<cstdlib>
5 #include<string>
6 #include<cstring>
7 #include<algorithm>
8 #include<functional>
9 #include<iomanip>
10 #include<numeric>
11 #include<cmath>
12 #include<queue>
13 #include<vector>
14 #include<set>
15 #include<cctype>
16 const double PI = acos(-1.0);
17 const int INF = 0x3f3f3f3f;
18 const int NINF = -INF - 1;
19 const int maxn = 1e3 + 5;
20 typedef long long ll;
21 #define MOD 1000000007
22 using namespace std;
23 int dp[maxn][2];
24 struct node
25 {
26 int x1, x2, h;
27 friend bool operator < (const node &m, const node &n)
28 {
29 return m.h < n.h;
30 }
31 }a[maxn];
32 int main()
33 {
34 int T;
35 scanf("%d", &T);
36 while (T--)
37 {
38 int n, x, y, maxm;
39 scanf("%d %d %d %d", &n, &x, &y, &maxm);
40 for (int i = 0; i <= n + 1; ++i) dp[i][0] = dp[i][1] = INF;
41 for (int i = 1; i <= n; ++i)
42 {
43 int p, q, c;
44 scanf("%d %d %d", &p, &q, &c);
45 a[i] = node{p, q, c};
46 }
47 a[0] = node{-20000, 20000, 0};
48 a[n + 1] = node{x, x, y};
49 sort(a, a + n + 1);
50 // for (int i = 0; i <= n + 1; ++i) cout << a[i].x1 << ' ' << a[i].x2 << ' ' << a[i].h << endl;
51 for (int i = 1; i <= n + 1; ++i)
52 {
53 int flag1 = 0, flag2 = 0;
54 for (int j = i - 1; j >= 0; --j)
55 {
56 if (a[i].h - a[j].h > maxm) break;
57 if (flag1 && flag2) break;
58 if (!flag1)
59 {
60 if (j == 0)
61 {
62 dp[i][0] = a[i].h;
63 flag1++;
64 }
65 else {
66 if (a[j].x1 <= a[i].x1 && a[j].x2 >= a[i].x1)
67 {
68 dp[i][0] = a[i].h - a[j].h + min(dp[j][0] + a[i].x1 - a[j].x1, dp[j][1] + a[j].x2 - a[i].x1);
69 flag1++;
70 }
71 }
72 }
73 if (!flag2)
74 {
75 if (j == 0)
76 {
77 dp[i][1] = a[i].h;
78 flag2++;
79 }
80 else {
81 if (a[j].x1 <= a[i].x2 && a[j].x2 >= a[i].x2)
82 {
83 dp[i][1] = a[i].h - a[j].h + min(dp[j][0] + a[i].x2 - a[j].x1, dp[j][1] + a[j].x2 - a[i].x2);
84 flag2++;
85 }
86 }
87 }
88 }
89 // cout << i << ' ' << dp[i][0] << ' ' << dp[i][1] << endl;
90 }
91 // cout << dp[n + 1][0] << ' ' << dp[n + 1][1];
92 printf("%d\n", min(dp[n + 1][0], dp[n + 1][1]));
93 }
94 return 0;
95 }