POJ 1925 Spiderman(DP)

题目链接

题意 : Spiderman从最左边的楼通过将蛛丝粘到后边的某座楼顶,然后荡过去,接着发射蛛丝荡过去,直到到达最后的楼。问最少发射几次蛛丝。

思路 :从横坐标 j 能跳过建筑物 i 需满足: (p[i].x - j)*(p[i].x - j) <= p[i].y*p[i].y  - (p[i].y - p[0].y)*(p[i].y-p[0].y). 从横坐标 j 经建筑物 i 后 到达横坐标 2 * p[i].x - j。

所以状态转移方程是: dp[2 * p[i] .x- j] = min(dp[2 * p[i].x - j] , d[j] + 1)。因为这个人走的是圆弧,每荡一次所达到的终点一定是与最开始的那座楼的高度等高。

先遍历楼,然后遍历位置,第二层循环找他要荡到哪儿,因为是对称的。

 1 //1925
 2 #include <cstdio>
 3 #include <string>
 4 #include <cstring>
 5 #include <iostream>
 6
 7 using namespace std ;
 8
 9 struct node
10 {
11     long long x ;
12     long long  y ;
13 }p[5120] ;
14 int dp[2051532] ;
15
16 int main()
17 {
18     int K ,N;
19     scanf("%d",&K) ;
20     while(K--)
21     {
22         scanf("%d",&N) ;
23         for(int i = 0 ; i < N ; i++)
24             scanf("%I64d %I64d",&p[i].x,&p[i].y) ;
25         memset(dp,100,sizeof(dp)) ;
26         dp[p[0].x] = 0 ;
27         for(int i = 1 ; i < N ; i++)
28             for(int j = p[i].x-1 ; j >= p[0].x ; j--)
29         {
30             long long  dis = (p[i].x-j)*(p[i].x-j)+(p[i].y-p[0].y)*(p[i].y-p[0].y) ;
31             if(dis > (long long)(p[i].y*p[i].y))
32                 break ;
33             dp[2*p[i].x-j] = min(dp[2*p[i].x-j],dp[j]+1) ;
34         }
35         int ans = 99999999 ;
36         for(int i = p[N-1].x ; i <= 2*p[N-1].x ; i++)
37             ans = min(ans,dp[i]) ;
38         if(ans >= 99999999)
39             ans = -1 ;
40         printf("%d\n",ans) ;
41     }
42     return 0 ;
43 }

POJ 1925 Spiderman(DP)

时间: 2024-08-16 20:50:17

POJ 1925 Spiderman(DP)的相关文章

poj 3342(树形dp)

题意:在一个公司中要举办一个聚会,每一个员工有一个奉献值.为了和谐规定直接上下级不能一起出席.让你找出奉献值之和最大为多少. 思路:dp[v][1]表示当前结点选,能获得的最大奉献值,dp[v][0]表示当前节点不选能获得的最大奉献值.状态转移: dp[v][0] = max(dp[v][0], ∑max(dp[x][1], dp[x][0]))x为直接儿子 dp[v][1] = max(dp[v][1], ∑dp[x][0] + vex[v]) 最后答案是max(dp[root][0], dp

poj 2151 概率dp

//poj 2151 概率dp 1 #include "iostream" 2 #include "cstdio" 3 #include "cstring" 4 #include "algorithm" 5 using namespace std; 6 double dp[33][33]; 7 int M, T, N; //problem, team, least 8 double p[1010][33]; 9 int mai

POJ 2250 Compromise (DP,最长公共子序列)

Compromise Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 6440 Accepted: 2882 Special Judge Description In a few months the European Currency Union will become a reality. However, to join the club, the Maastricht criteria must be fulfille

poj 1947(树形dp)

题意:一棵树上问你最少切掉几条边使得能分割出一个结点数正好为k的子树. 思路:dp[i][j]表示以i为根切掉j个结点最少要几条边. dp[v][j] = min(dp[v][j], dp[v][j-k] + dp[x][k]); 代码如下: 1 dp[v][j] = min(dp[v][j], dp[v][j-k] + dp[x][k]); 2 } 3 } 4 } 5 } 6 } 7 return vex[v]; 8 } 9 10 int main() 11 { 12 // freopen("

POJ 2486 树形DP

有一颗苹果树,每个节点上面有很多苹果,从一个节点到另外一个可以到达的节点花费1步,求k步最多能吃到多少苹果,起始点为1,可以不回到起始点. 这是典型的回溯型树状dp. dp[i][j][0]代表以i为根节点的子树最多j步后回到i能吃到的最多的苹果, dp[i][j][1]代表以i为根节点的子树最多j步后不回到i节点最多能吃到的子树.那么状态转移就分三步了. (1)dp[i][j+2][0] = max(dp[i][j+2][0], dp[i][j-k][0]+dp[son][k][0]); (2

POJ 2411 插头DP

1 //插头DP,算是广义路径的吧. 2 /* 3 我是这样想的,定义填数的为0,未填的为1.然后,初始自然是(0,0).我还定义了整个棋盘的状态,不知是否多此一举. 4 这样,把轮廓线上的格子状态记录.当(I,J)上方的格子为空,必定要填一个竖的.当左边格子为空,当前可填一个横的,也可不填. 5 当左边格子不为空,当前格子必为空...AC. 6 */ 7 8 #include <iostream> 9 #include <cstdio> 10 using namespace st

poj 1458 动态规划DP

//  poj 1458  zoj 1733  最长公共子序列  DP #include <iostream>#include <string.h>#define N 1005using namespace std ;char  s1[N],s2[N];   int dp[N][N];int max(int a,int b)   {    return a>b ? a : b ;  }void f(int n,int m){   int i,j;    for (i=0; i

POJ 3701 概率DP

给定2^n 支足球队进行比赛,n<=7. 队伍两两之间有一个获胜的概率,求每一个队伍赢得最后比赛的概率是多少? 状态其实都是很显然的,一开始觉得这个问题很难啊,不会.dp[i][j] 表示第i支队伍赢得前j轮比赛的概率.(这个题目处理区间的时候比较恶心,小心点即可). 1:   2: #include <iostream> 3: #include <cstdio> 4: #include <cstring> 5: #include <map> 6: #

POJ 3342 树形DP入门题

题目意思和POJ2342一样,只是多加了一个条件,如果最大方案数唯一,输出Yes,不唯一输出No dp的是时候多加一个变量记录答案是否唯一即可 #include "stdio.h" #include "string.h" #include "vector" using namespace std; struct node { int fa; vector<int>child; }data[210]; struct comp { int