help Jimmy(動態規劃) (我以爲是此題最詳細的解答!!!歡迎糾正)(附測試數據)

"Help Jimmy" 是在下圖所示的場景上完成的遊戲。 ios


場景中包括多個長度和高度各不相同的平臺。地面是最低的平臺,高度爲零,長度無限。

Jimmy老鼠在時刻0從高於全部平臺的某處開始下落,它的下落速度始終爲1米/秒。當Jimmy落到某個平臺上時,遊戲者選擇讓它向左仍是向右跑,它跑動的速度也是1米/秒。當Jimmy跑到平臺的邊緣時,開始繼續下落。Jimmy每次下落的高度不能超過MAX米,否則就會摔死,遊戲也會結束。

設計一個程序,計算Jimmy到底地面時可能的最先時間。 函數


Input 第一行是測試數據的組數t(0 <= t <= 20)。每組測試數據的第一行是四個整數N,X,Y,MAX,用空格分隔。N是平臺的數目(不包括地面),X和Y是Jimmy開始下落的位置的橫豎座標,MAX是一次下落的最大高度。接下來的N行每行描述一個平臺,包括三個整數,X1[i],X2[i]和H[i]。H[i]表示平臺的高度,X1[i]和X2[i]表示平臺左右端點的橫座標。1 <= N <= 1000,-20000 <= X, X1[i], X2[i] <= 20000,0 < H[i] < Y <= 20000(i = 1..N)。全部座標的單位都是米。

Jimmy的大小和平臺的厚度均忽略不計。若是Jimmy剛好落在某個平臺的邊緣,被視爲落在平臺上。全部的平臺均不重疊或相連。測試數據保證問題必定有解。
Output 對輸入的每組測試數據,輸出一個整數,Jimmy到底地面時可能的最先時間。 Sample Input
1
3 8 17 20
0 10 8
0 10 13
4 14 3
Sample Output
23



題解:
1.首先Jimmy是從高向低掉落,因此首先你須要將輸入的板塊按照高度的順序由高到低排列,並且與其相對應的左右橫座標也須要更新
2.排序以後,思考Jimmy的位置,一開始,它的位置是一個點,那麼他只能夠垂直向下掉落,並且只有倆種狀況
  (1)直接落地(前提是這個高度要小於MAX, 否則它就摔死了)
  (2)掉落到第一塊板子上
3.要注意,板塊不能夠穿越!並且有一種邊緣狀況,就是你從上一塊板塊的邊緣落下,正好落到了下一塊的板塊的邊緣,它是能夠停留的(就像以前手機上玩的遊戲跳跳球同樣)
4.從新回到Jimmy落到了一塊板塊的中央,這是先無論它, 你只須要知道它落到了哪一個板塊上, 並把它存儲起來
5.這時咱們從第一個板塊提及,也就是最高的那個板塊,咱們來討論從它的邊緣下落問題,能夠分爲倆個問題, 從左邊緣下落, 右邊緣下落
  因而能夠獲得(以左邊緣下落爲例子,右邊緣相同)
  if(板子k左端正下方沒有別的板子){
    if(板子k的高度h(k)大於MAX)
      LeftMinTime(k) = INF(很大的數)
    else
      LeftMinTime(k) = h(k);
   }
   else if(板子k左端正下方的板子編號時m)//這裏須要注意,僅當倆塊板子的高度差小於MAX才能執行下面的語句,不然Jimmy會被摔死,則Time爲INF(很是重要)
      LeftMinTime(k) = h(k) - h(m) + Min(LeftMinTime(m) + Lx(k) - Lx(m), RightMinTime(m) + Rx(m) - Lx(k));
  }
6.對於尋找下方是否有板子能夠設置一個函數find
 int find(int x, int h) {//x爲Jimmy所在的橫座標,h爲當前板子的高度
    for (int i = 0; i < N; i++) {
        if (x >= X1[i] && x <= X2[i]) {
            if (h > H[i] && H[i] != 0)//這裏要保證H[i]不爲0,由於地面是0,樹立在地面的板子是沒有意義的
                return i;
        }
    }
    return -1;
 }

測試數據
2

3 8 7 2
6 14 6
4 10 4
5 14 2

1 6 10 20
2 3 5

answer:
17 10

1
4 14 5 6
3 22 1
16 23 2
16 30 3
13 21 4
答案:15
1
2 2 12 8
0 10 10
2 12 5
答案:22

1
3 8 17 20
8 10 8
8 10 13
8 14 3
ans:17

1
60 822 302 50
813 823 298
813 823 293
816 826 213
816 826 178
817 827 218
813 823 148
821 831 73
814 824 248
813 823 283
815 825 158
819 829 58
814 824 13
813 823 28
819 829 233
814 824 43
773 783 293
821 831 93
818 828 268
816 826 198
818 828 113
814 824 208
816 826 68
821 831 133
794 804 248
814 824 108
829 839 28
818 828 143
844 854 298
802 812 133
801 811 28
818 828 238
817 827 8
816 826 48
820 830 3
819 829 288
822 832 138
820 830 183
855 865 13
777 787 268
820 830 63
789 799 28
822 832 33
855 865 213
779 789 208
836 846 248
806 816 33
821 831 263
818 828 83
846 856 263
789 799 68
854 864 8
854 864 283
801 811 298
805 815 143
822 832 23
821 831 173
813 823 153
858 868 138
818 828 98
839 849 133
答案:352 

 

代碼 :
  1 #include<iostream>
  2 #include<algorithm>
  3 #include<cstring>
  4 using namespace std;
  5 
  6 static const int MAXLEN = 1010;
  7 
  8 #define INF 1e9;
  9 
 10 int t, N, X, Y, MAX;
 11 int X1[MAXLEN] = { 0 }, X2[MAXLEN] = { 0 }, H[MAXLEN] = { 0 }, LeftMinTime[MAXLEN] = { 0 }, RightMinTime[MAXLEN] = { 0 };
 12 
 13 void h_sort(int X1[], int X2[], int H[]) {
 14     for (int i = 0; i < N; i++) {
 15         for (int j = i + 1; j < N; j++) {
 16             if (H[j] > H[i]) {
 17                 int temp;
 18                 temp = H[i];
 19                 H[i] = H[j];
 20                 H[j] = temp;
 21                 temp = X1[i];
 22                 X1[i] = X1[j];
 23                 X1[j] = temp;
 24                 temp = X2[i];
 25                 X2[i] = X2[j];
 26                 X2[j] = temp;
 27             }
 28         }
 29     }
 30 }
 31 
 32 int find(int x, int h) {
 33     for (int i = 0; i < N; i++) {
 34         if (x >= X1[i] && x <= X2[i]) {
 35             if (h > H[i] && H[i] != 0)
 36                 return i;
 37         }
 38     }
 39     return -1;
 40 }
 41 
 42 int main() {
 43     cin >> t;
 44     while (t--) {
 45         memset(X1, 0, sizeof(X1));
 46         memset(X2, 0, sizeof(X2));
 47         memset(H, 0, sizeof(H));
 48         memset(LeftMinTime, 0, sizeof(LeftMinTime));
 49         memset(RightMinTime, 0, sizeof(RightMinTime));
 50         cin >> N >> X >> Y >> MAX;
 51         for (int i = 0; i < N; i++)
 52             cin >> X1[i] >> X2[i] >> H[i];
 53 
 54         //排序
 55         h_sort(X1, X2, H);
 56         //第一塊板子 
 57         int key = find(X, Y);
 58 
 59         if (key == -1) {
 60             cout << Y << endl;
 61             continue;
 62         }
 63 
 64         for (int i = N - 1; i >= 0; i--) {
 65             int m = find(X1[i], H[i]);
 66             if (m == -1) {
 67                 if (H[i] > MAX) {
 68                     LeftMinTime[i] = INF;
 69                 }
 70                 else {
 71                     LeftMinTime[i] = H[i];
 72                 }
 73             }
 74             else {
 75                 if(H[i] - H[m] <= MAX)
 76                     LeftMinTime[i] = H[i] - H[m] + min(LeftMinTime[m] + X1[i] - X1[m], RightMinTime[m] + X2[m] - X1[i]);
 77                 else 
 78                     LeftMinTime[i] = INF;
 79             }
 80             int r = find(X2[i], H[i]);
 81             if (r == -1) {
 82                 if (H[i] > MAX) {
 83                     RightMinTime[i] = INF;
 84                 }
 85                 else {
 86                     RightMinTime[i] = H[i];
 87                 }
 88             }
 89             else {
 90                 if(H[i] - H[r] <= MAX)
 91                     RightMinTime[i] = H[i] - H[r] + min(LeftMinTime[r] + X2[i] - X1[r], RightMinTime[r] + X2[r] - X2[i]);
 92                 else
 93                     RightMinTime[i] = INF;
 94             }
 95         }
 96         int minTime = Y - H[key] + min(LeftMinTime[key] + X - X1[key], RightMinTime[key] + X2[key] - X);
 97         cout << minTime << endl;;
 98     }
 99     return 0;
100 }
相關文章
相關標籤/搜索