您的位置:首页 > 其它

poj 1925_Spiderman(坐标DP)

2017-02-08 14:01 609 查看
http://poj.org/problem?id=1925

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


题目大意:

给出n个建筑,每个建筑以两个数x,y表示,x代表它在横轴上的位置,y代表这个建筑的高度。所有建筑的高度都大于等于第一个建筑的高度。所有建筑输入顺序按照x,y从小到达的顺序排列。

蜘蛛侠在第一个建筑上,他要去最后一个建筑救女朋友。一直他每一次摇摆都会到关于建筑对称的位置。求到最后一个建筑的最小摇摆次数。

基本思路:

Dp横坐标x,dp[x]表示当荡到x这个位置时的最小摇摆次数。可以发现除了摇摆到最后一个建筑,其他都是在一个水平线上的,即与蜘蛛侠的公寓的高度相等,且是对称前进的。然后枚举每个建筑,假设在第i个建筑上建顶点进行摇摆时,先计算出在该位置摇摆时的范围,保证不要碰到地面。如果dp[q[i].x-j]!=-1,即q[i].x-j这个点来过时,那么状态转移方程为dp[q[i].x+j]=dp[q[i].x-j]+1,如果dp[q[i].x-j]==-1的话表示没有摇摆的该点,显然不能到对称点q[i].x+j。

#include <iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<cstdlib>

using namespace std;

struct node
{
long long x,y;
}q[5005];
int dp[1000050];

int main()
{
int t;
int n;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%lld%lld",&q[i].x,&q[i].y);
}
memset(dp,-1,sizeof(dp));
dp[q[0].x]=0;
for(int i=1;i<n;i++)
{
int dis=sqrt(q[i].y*q[i].y-(q[i].y-q[0].y)*(q[i].y-q[0].y));
for(int j=1;j<=dis;j++)
{
if(q[i].x-j<q[0].x)break;
if(dp[q[i].x-j]==-1)continue;
else
{
int temp=min(q[i].x+j,q[n-1].x);
if(dp[temp]==-1)dp[temp]=dp[q[i].x-j]+1;
else
{
dp[temp]=min(dp[temp],dp[q[i].x-j]+1);
}
}
}
}
printf("%d\n",dp[q[n-1].x]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: