这道题自己是水过的,,,交完之后看了网上的代码是DP,,我。。。
时间还算不错,跑了400MS。
题意:蜘蛛侠从初始的塔开始,利用一栋栋楼做圆周摆,到达最后的塔楼。并且每次摆长不能大于楼高。
题解:首先,每次的圆周摆要完成之后才可以进行下一次的移动,所以每次的圆周摆,始末位置是关于塔楼对称的。根据楼高可以算出能进行圆周摆的范围,然后就枚举。。
我在讲什么啊去QAQ。。。
#include <stdio.h>
#include <math.h>
#include <iostream>
#include <queue>
using namespace std;
#define maxn 1000100
#define inf 1000100
#define ll long long
ll pos[maxn<<1]; //记录每次摇摆后到达的位置
ll min(ll x,ll y){return x<y?x:y;}
void init()
{
for(int i=0;i<(maxn<<1);i++) {pos[i]=inf;}//printf("%d\n",pos[i]);}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
init();
scanf("%d",&n);
ll i,k;
ll st,j,d,x,h;
scanf("%lld%lld",&st,&d);
pos[st]=0;
for(i=0;i<n-1;i++)
{
scanf("%lld%lld",&x,&h);
int dd=sqrt(2*h*d-d*d); //能进行摇摆的范围[x-dd,x-1]
for(j=x-dd<0?0:x-dd;j<x;j++)
if(pos[j]!=inf)
// if(x==7) printf("j=%d pos[j]=%d 2*x+\n",j,pos[j]);
{pos[2*x-j]=min(pos[2*x-j],pos[j]+1);} //假设有多种方式可以到达同一个位置,挑最小的那个
// for(k=0;k<=x;k++) printf("pos[%d]=%d ",k,pos[k]);printf("\n");
// printf("pos[%d]=%d\n",2*x+j,pos[2*x+j]);
}
ll ans=inf;
for(i=x;i<=2*x;i++)
ans=min(pos[i],ans);
if(ans==inf) ans=-1;
printf("%lld\n",ans);
}
return 0;
}