太挫了,又是从别人那里偷来的代码
因为一开始想枚举楼dp,但一直无法解决后效性,到达一高楼的次数一样但甩开到达右边的横坐标不一样
而且题意没有理解到,高度在h[1]时才转移到下一高楼
这一题告诉我们枚举坐标也是有可能的,再加适当剪枝也许能实现
还有个坑:数组要开两倍大小,因为甩开到达右边相当于镜面对称
#include <iostream>
#include <stdio.h>
#include <cstring>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <map>
#include <set>
#include<iterator>
#include <algorithm>
#include <string>
using namespace std;
#define SIZE 2000500
#define N 5050
int dp[SIZE],n;
long long h[N],x[N];
int main ()
{
int test;scanf("%d",&test);
while(test--)
{
scanf("%d",&n);
for(int i=1;i<=n;++i)
scanf("%lld%lld",&x[i],&h[i]);
memset(dp,-1,sizeof(dp));
//int p;
dp[x[1]]=0;
for(int i=2;i<=n;++i)
{
for(int j=x[i]-1;j>=0;--j)
if(dp[j]>=0)
{
if((x[i]-j)*(x[i]-j)+(h[i]-h[1])*(h[i]-h[1])<=h[i]*h[i])
{
int rr=2*x[i]-j;
if(dp[rr]==-1 || dp[rr]>dp[j]+1)
{
dp[rr]=dp[j]+1;
if(rr>=x[n] && (dp[x[n]]==-1 || dp[x[n]]>dp[rr]))
dp[x[n]]=dp[rr];
}
}
else break;
}
}
printf("%d\n",dp[x[n]]);
}
return 0;
}