我是用DP做的。 一开始把坐标放在最外层循环,然后枚举在该坐标之后的所有building,得到下一个坐标点。TLE。 后来换成把building放在外层循环,然后根据建筑物高度枚举可选的坐标点范围,ac。囧。 #include "math.h" #include <iostream> using namespace std; const int maxn=1000000; double start_height; int n,min_swing,end_x; int building[5005][2]; int swing[maxn]; #define MinN(x,y) ((x)<(y)?(x):(y)) int Max_length(double x,double y)//绳子长度小于等于建筑物高度 { return sqrt(2*y*start_height-start_height*start_height); } void DP() { min_swing=INT_MAX; memset(swing,-1,sizeof(swing)); swing[building[0][0]]=0; for(int i=1;i<n;i++) { int last_position=building[i][0]-Max_length(building[i][0],building[i][1]); for(int j=building[i][0]-1;j>=last_position&&j>=building[0][0];j--) { if(swing[j]==-1||swing[j]+1>=min_swing) continue; int next_x=building[i][0]*2-j; if(next_x>=end_x) { min_swing=MinN(swing[j]+1,min_swing); continue; } if(swing[next_x]==-1) swing[next_x]=swing[j]+1; else swing[next_x]=MinN(swing[next_x],swing[j]+1); } } } int main() { int t; scanf("%d",&t); while(t--) { scanf("%d",&n); min_swing=maxn; for(int i=0;i<n;i++) { scanf("%d%d",&building[i][0],&building[i][1]); } start_height=building[0][1]; end_x=building[n-1][0]; DP(); if(min_swing==INT_MAX) printf("-1/n"); else printf("%d/n",min_swing); } return 0; }