您的位置:首页 > 其它

poj-1925 Spiderman

2011-07-08 22:09 453 查看
dp

d[i] 表示从apartment到 横坐标 i 最少需跳几步。。 p[i] 建筑物 i 的横坐标, h[i]建筑物i的纵坐标

注意 由对称性,spiderman的纵坐标始终是 apartment 的高度!! 所以不需要管纵坐标!!

遍历每个建筑物。。

  从横坐标 j 能跳过建筑物 i 需满足: (p[i] - j)^2 <= h[i] ^ 2 - (h[i] - h[1]) ^2

从横坐标 j 经建筑物 i 后 到达横坐标 2 * p[i] - j。。

  综上, d[2 * p[i] - j] = min(d[2 * p[i] - j] , d[j] + 1)...

最后注意到达west tower的步数的处理

/*
* 1925.cpp
*
* Created on: 2011-7-8
* Author:
*/
#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;

const int MAXN = 5000 + 5;
const int MAX_X = 2000000 + 5;
const int INF = 1000000;

int n;
int p[MAXN], h[MAXN];
double scale[MAXN];
int d[MAX_X];

int main(){
int tot;
scanf("%d", &tot);
while(tot--){
scanf("%d", &n);

for(int i=1; i<=n; i++){
scanf("%d%d", &p[i], &h[i]);
// scale[i] = sqrt((double) h[i] * h[i] - (h[i] - h[1]) * (h[i] - h[1]));    //注意不要用sqrt,否则TLE!! (后面比较的时候用平方)
      scale[i] = h[i] * h[i] - (h[i] - h[1]) * (h[i] - h[1]);
}

memset(d, -1, sizeof(int) * MAX_X);  //也可以for循环。。 d[i] = INF 为了节省时间,直接设为-1, 之后判断。。
d[p[1]] = 0;

//……
for(int i=2; i<=n; i++){
for(int j = p[i]-1; j>=p[1]; j--){
if(d[j] == -1) continue; //!!!!  直接跳过~

int gap = p[i] - j;
if(gap * gap> scale[i]) break;  //gap的平方和scale比较

int aim = 2*p[i]-j;
if( (d[ aim ]==-1 || d[ aim ] > d[j] + 1) ){
d[ aim ] = d[j] + 1;
}

if(aim >= p
&& (d[p
] == -1 || d[p
] > d[ aim ])){  //最后的处理
d[p
] = d[ aim ];
}
}
}

if(d[p
] <= 0)
printf("-1\n");
else
printf("%d\n", d[p
]);

}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: