POJ 1661Help Jimmy(dp)

Help Jimmy
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 9708   Accepted: 3147

Description

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

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

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

Source

dp[i][0]表示到達第i塊平臺的右邊花費的最小時間,dp[i][1]表示到達第i塊平臺的左邊的最小時間,判斷上次能否達到然後轉移即可。
注意要先排序。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
struct node
{
    int h, l, r;
} s[1100];
const int inf = 0x3f3f3f3f;
bool cmp(node a, node b)
{
    return a.h > b.h;
}
int dp[1100][2];
int main()
{
    int t, x, y, maxh, n;
    cin>>t;
    while(t--)
    {

        scanf("%d%d%d%d", &n, &x, &y, &maxh);
        for(int i = 1; i<=n+1; i++)
            dp[i][0] = dp[i][1] = inf;
        s[0].h = y;
        s[0].l = s[0].r = x + 20000;
        for(int i = 1; i<=n; i++)
        {
            scanf("%d%d%d", &s[i].l, &s[i].r, &s[i].h);
            s[i].l += 20000;
            s[i].r += 20000;
        }
        s[n+1].h = 0;
        s[n+1].l = 0, s[n+1].r = 40000;
        dp[0][0] = dp[0][1] = 0;
        sort(s, s+n+2, cmp);
        for(int i = 0; i<=n; i++)
        {
            for(int k = 0; k<=1; k++)
            {
                for(int j = i+1; j<=n+1; j++)
                {
                    if(j == n+1 && s[i].h - s[j].h <= maxh)
                    {
                        if(k == 1)
                            dp[j][1] = min(dp[j][1], dp[i][1]);
                        if(k == 0)
                            dp[j][0] = min(dp[j][0], dp[i][0]);
                    }
                    else
                    {
                        if(s[i].h - s[j].h <= maxh)
                        {
                            if(k == 0)
                            {
                                if(s[j].l<=s[i].r && s[j].r >= s[i].r)
                                {
                                    dp[j][0] = min(dp[j][0], dp[i][0] + s[j].r - s[i].r);
                                    dp[j][1] = min(dp[j][1], dp[i][0] + s[i].r - s[j].l);
                                    break;

                                }
                            }
                            else
                            {
                                if(s[j].l <= s[i].l && s[j].r >= s[i].l)
                                {
                                    dp[j][0] = min(dp[j][0], dp[i][1] + s[j].r - s[i].l);
                                    dp[j][1] = min(dp[j][1], dp[i][1] + s[i].l - s[j].l);
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }
          //for(int  i = 0; i<=n+1; i++)
         //cout<<dp[i][1]<<" "<<dp[i][0]<<endl;
         cout<<min(dp[n+1][0], dp[n+1][1]) + y<<endl;
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章