您的位置:首页 > 其它

poj1925-Spiderman(dp)

2013-07-18 19:43 316 查看
题目连接

题意:

  蜘蛛侠从他最初所在的位置,到西塔,要经过一些高楼。而蜘蛛侠是从他所在的位置最高处出发,发出蛛丝粘在另一个楼的最高处,像荡秋千一样前行,它最远只能荡到

对应的高度。如果荡到地面就不能再前行了。问你他达到西塔最小发出的蛛丝的次数。

分析:

自己不会!看下学长的。


点击打开链接

自己分析了一些:

 根据题意。“蜘蛛哥”荡到的高度都等于第一个位置的高度。那么,问题就简化了。对高度就不必关心了,只要转化横坐标的区间来判断是否可以荡。这个应该很好理解。

另外,知道一个楼的高度h和位置x,如果蜘蛛哥幸运地从地面扫过。那么,在高度为H(前面已经知道,他荡的最高的高度只与第一个有关)的上空,这样,它的范围:

由勾股定理得 :     x-√(h^2-(h-H)^2)<=r<=x+√(h^2-(h-H)^2)    

化解就为: x-√(2hH-H^2)<=r<=x+√(2hH-H^2);

这样相当于把x轴往上平移了H的高度。

理解上面的。再就是dp了。看连接吧!

还是厚着脸皮贴个代码吧!

#include<cstdio>
#include<cmath>
#include<cstring>
#define INF 0x3f3f3f3f
#include<algorithm>
using namespace std;
struct node{
int x,y,r;
}p[5005];

int n,dp[1000005];

int solve()
{
int ans=INF;
memset(dp,0x3f,sizeof(dp));
dp[p[1].x]=0;
for(int i=2;i<=n;i++){
int a=p[i].r,b=p[i].x;
for(int j=a;j<b;j++){
int c=2*p[i].x-j;
if(c<p
.x)
dp[c]=min(dp[c],dp[j]+1);
else
ans=min(ans,dp[j]+1);
}
}
if(ans==INF) return -1;
return ans;
}

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