ACM: 动态规划题 poj 1925

来源:互联网 发布:金山tw域名遭抢注 编辑:程序博客网 时间:2024/06/08 02:54
Spiderman
Description
Dr. Octopus kidnappedSpiderman's girlfriend M.J. and kept her in the West Tower. Now thehero, Spiderman, has to reach the tower as soon as he can to rescueher, using his own weapon, the web.

From Spiderman's apartment, where he starts, to the tower there isa straight road. Alongside of the road stand many tall buildings,which are definitely taller or equal to his apartment. Spidermancan shoot his web to the top of any building between the tower andhimself (including the tower), and then swing to the other side ofthe building. At the moment he finishes the swing, he can shoot hisweb to another building and make another swing until he gets to thewest tower. Figure-1 shows how Spiderman gets to the tower from thetop of his apartment – he swings from A to B, from B to C, and fromC to the tower. All the buildings (including the tower) are treatedas 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 heightof the building. Notice that during Spiderman's swings, he cannever go backwards.
ACM: <wbr>动态规划题 <wbr>poj <wbr>1925

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

Input

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

Output

For each test case, output oneline containing the minimum number of swings (if it's possible toreach 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

 

题意: 蜘蛛侠去救女友, 每次用web射在楼顶, 然后经过一个扇形弧线, 继续发射web, 知道最右端

     的west tower, 现在要求出用最少的跳跃次数到达west tower.

 

解题思路:

    1. 题意很清晰, 每次蜘蛛侠的射出web的长度是小于等于下一个建筑的高度.

       即: 距离下个建筑最大距离: dist[i] = sqrt( y[i]*y[i] - (y[i]-y[1])*(y[i]-y[1]));

           从横坐标为j的位置要越过建筑i: x[i]-j <= dist[i];

       然后经过一个扇形弧线达到: 2*x[i]-j的位置.

     2. 设dp[i]:表示到达横坐标为i的位置需要最少的跳跃次数.

        动态方程: dp[ 2*x[i]-j ] = min( dp[2*x[i]-j ], dp[j]+1 );

 

代码:

#include <cstdio>
#include <iostream>
#include <cstring>

using namespace std;
#define MAX 2000005
#define SIZE 5005

int n;
int x[SIZE], y[SIZE];
int dp[MAX], dist[SIZE];

inline int min(int a, int b)
{
 return a < b ? a : b;
}

int DP()
{
 dp[x[1]] = 0;
 for(int i = 2; i <= n; ++i)
 {
  for(int j = x[i]-1; j>= x[1]; --j)
  {
   if(dp[j] ==-1) continue;
   if((x[i]-j)*(x[i]-j) > dist[i] ) break;

   if( dp[2*x[i]-j ] == -1 || dp[ 2*x[i]-j ] > dp[j]+1)
    dp[2*x[i]-j ] = dp[j]+1;

   if(2*x[i]-j >= x[n]&&  (dp[ x[n] ] ==-1 || dp[ x[n] ] > dp[ 2*x[i]-j ]) )
    dp[x[n] ] = dp[ 2*x[i]-j ];
  }
 }
 return dp[ x[n] ];
}

int main()
{
// freopen("input.txt", "r", stdin);
 int caseNum, i;
 scanf("%d",&caseNum);
 while(caseNum--)
 {
  scanf("%d",&n);
  for(i = 1; i <=n; ++i)
  {
   scanf("%d%d",&x[i], &y[i]);
   dist[i] =y[i]*y[i]-(y[i]-y[1])*(y[i]-y[1]);
  }

  memset(dp, -1,sizeof(dp));
  printf("%d\n",DP());
 }
 return 0;
}

0 0
原创粉丝点击