POJ 1925 Spiderman(線性dp)

畫船聽雨發表於2014-06-03

題意很好懂就是蜘蛛俠去救人,開始在自己的apartment裡,需要趕到west tower裡。途中有許多building。給出每一個building的位置和高度。spiderman可以塗絲掛到某個building的頂端,然後swing,就像盪鞦韆一樣。求spiderman最少要蕩多少次。一開始的時候不理解為什麼可以蕩過比它高的building,後來一想他完全可以繞過去啊。所以這裡的重點是他每次到達的點都是起點的對稱位置。

用座標但作為dp的值,但是一開始就是找不到可以到達的條件,各種蛋疼,無奈啊、、、後來才發現原來條件是得構成一個直角三角形,否則是不可能到達的啊。sad、、這樣就解決了怎麼過來的問題了啊,直接就可以dp了啊。

x表示列舉的點到building[i]的距離,y表示building[i]與building[0]的高度差,z表示building[i]的高度。這樣的的話,如果能蕩過來的話那條斜邊的長度z^2 = x^2+y^2。z就是那條斜邊啊、、sad,怎麼一開始沒發現啊、、

Spiderman
Time Limit: 5000MS   Memory Limit: 65536K
Total Submissions: 6091   Accepted: 1195

Description

Dr. Octopus kidnapped Spiderman's girlfriend M.J. and kept her in the West Tower. Now the hero, Spiderman, has to reach the tower as soon as he can to rescue her, using his own weapon, the web. 

From Spiderman's apartment, where he starts, to the tower there is a straight road. Alongside of the road stand many tall buildings, which are definitely taller or equal to his apartment. Spiderman can shoot his web to the top of any building between the tower and himself (including the tower), and then swing to the other side of the building. At the moment he finishes the swing, he can shoot his web to another building and make another swing until he gets to the west tower. Figure-1 shows how Spiderman gets to the tower from the top of his apartment – he swings from A to B, from B to C, and from C to the tower. All the buildings (including the tower) are treated as straight lines, and during his swings he can't hit the ground, which means the length of the web is shorter or equal to the height of the building. Notice that during Spiderman's swings, he can never go backwards. 

You may assume that each swing takes a unit of time. As in Figure-1, Spiderman used 3 swings to reach the tower, and you can easily find out that there is no better way.

Input

The first line of the input contains the number of test cases K (1 <= K <= 20). Each case starts with a line containing a single integer N (2 <= N <= 5000), the number of buildings (including the apartment and the tower). N lines follow and each line contains two integers Xi, Yi, (0 <= Xi, Yi <= 1000000) the position and height of the building. The first building is always the apartment and the last one is always the tower. The input is sorted by Xi value in ascending order and no two buildings have the same X value.

Output

For each test case, output one line containing the minimum number of swings (if it's possible to reach the tower) or -1 if Spiderman can't reach the tower.

Sample Input

2
6
0 3
3 5
4 3
5 5
7 4
10 4
3
0 3
3 4
10 4

Sample Output

3
-1
#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
#include <stdio.h>
#include <string>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <set>
#define eps 1e-8
#define M 1000100
//#define LL __int64
#define LL long long
#define INF 0x7ffffff
#define PI 3.1415926535898


const int maxn = 1000010;

using namespace std;

int dp[maxn];
struct node
{
    int x, y;
} f[maxn];

int main()
{
    int T;
    cin >>T;
    while(T--)
    {
        int n;
        cin >>n;
        for(int i = 0; i < n; i++)
            scanf("%d %d", &f[i].x, &f[i].y);
        int m = f[n-1].x;
        for(int i = 0; i <= m; i++)
            dp[i] = INF;
        dp[0] = 0;
        for(int i = 1; i < n; i++)
        {
            LL z = f[i].y;
            LL y = f[i].y-f[0].y;
            for(int j = f[i].x-1; j >= f[0].x; j--)
            {
                LL x = f[i].x-j;
                if(z*z < x*x+y*y)
                    break;
                int s = f[i].x+x;
                if(s > m)
                    s = m;
                dp[s] = min(dp[s], dp[j]+1);
            }
        }
        if(dp[m] == INF)
            cout<<"-1"<<endl;
        else
            cout<<dp[m]<<endl;
    }
    return 0;
}


相關文章