POJ 1925 Spiderman(dp)

Posted 小胡子Haso

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 1925 Spiderman(dp)相关的知识,希望对你有一定的参考价值。

【POJ 1925】 Spiderman(dp)


Time Limit: 5000MS Memory Limit: 65536K
Total Submissions: 6806 Accepted: 1361

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


最近卡在各种题上,各种不爽。。。昨天开始啃这题,最后也没A,今天搞了搞印象笔记,不得不说,是个好APP,。金巨安利给窝的,后来又跟金巨请教了请教数论相关的知识


刚刚想起来这题,打算接着啃,结果瞟了一眼,立马发现有个Int,感觉会乘爆,甚至确定是这里的问题了……改了交了发,果然=.=



扯远了,这题题意:一个王子or骑士or狂战士or蝙蝠侠or蜘蛛侠。。。恩,蜘蛛侠比较像

在最左边的城堡顶端,公主or......,。在最右端的。。。恩……塔中。。。

现在蜘蛛侠要去救公主,每次他可以选择一个塔顶作为支点,然后荡到右边同高度的未知,也就是右移相同的横坐标(如图所示


规定荡下来不可以着地,也就是绳子要小于等于作为支点的塔高。


问最少需要经过几个塔。如果不存在合法的方案,输出-1。

题目保证第一个塔是起点,并且之后的塔都高于或同高于第一个塔。





题目很友好了……然而卡了一下午不友好的代码……只怪不够强=。=

刚开始我是枚举横坐标,然后找后面的塔,如果合法,就通过这个塔荡过去(更新右边到达的地方的塔数

这样是n*m的,,炸掉了

后来换过来,枚举塔,然后从最左可行的起点到该塔,挨个荡过去,WA。。。

然后今天把一处的int改成long long就过了=.=人生如梦%…………

另外要注意,题目中到达公主塔的定义是碰到即可


代码如下:

#include <iostream>
#include <cmath>
#include <vector>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <queue>
#include <stack>
#include <list>
#include <algorithm>
#include <map>
#include <set>
#define LL long long
#define Pr pair<int,int>
#define fread() freopen("in.in","r",stdin)
#define fwrite() freopen("out.out","w",stdout)

using namespace std;
const int INF = 0x3f3f3f3f;
const int msz = 10000;
const int mod = 1e9+7;
const double eps = 1e-8;

int dp[2000100];
pair <LL,LL> pr[5555];

int main()

	//fread();
	//fwrite();

	int t,n,h,pos,mn,nt;
	scanf("%d",&t);
	while(t--)
	
		scanf("%d",&n);
		memset(dp,-1,sizeof(dp));
		//读取蜘蛛侠所在塔位置和高度
		scanf("%d%d",&pos,&h);

		for(int i = 1; i < n; ++i)
			scanf("%lld%lld",&pr[i].first,&pr[i].second);

		dp[pos] = 0;
		mn = INF;
		//枚举塔
		for(int i = 1; i < n; ++i)
		
			//printf("x:%lld y:%lld\\n",pr[i].first,pr[i].second);
			//就是这里…………#¥%#¥%¥#%
			LL x = pr[i].first;
			LL y = pr[i].second;

			//枚举左边可行的起点
			for(int j = max(pos,(int)x-(int)sqrt((y*y-(y-h)*(y-h))*1.0)); j < x; ++j)
			
				//printf("dp[%d]:%d\\n",pos,dp[pos]);
				if(dp[j] == -1) continue;

				nt = pr[i].first*2-j;
				//printf("%d/%lld\\\\%d\\n",pos,pr[j].first,nt);
				//如果能荡到最右边的塔
				if(nt >= pr[n-1].first)
				
					mn = min(mn,dp[j]+1);
				else if(dp[nt] == -1 || dp[nt] > dp[j]+1) dp[nt] = dp[j]+1;
			
		
		printf("%d\\n",mn == INF? -1: mn);
	

	return 0;






以上是关于POJ 1925 Spiderman(dp)的主要内容,如果未能解决你的问题,请参考以下文章

POJ2397DP搜索

bzoj 1925 dp

BZOJ 1925 地精部落(DP)

bzoj1925地精部落[SDOI2010](dp)

poj1180 Batch Scheduling -斜率优化dp

BZOJ1925: [Sdoi2010]地精部落 DP+滚动数组