Solution:
这题不难想到一个 (mathcal{O(n^2)}) 的朴素 (dp) 我们可以设计一个状态 (f[i]) 表示前 (i) 个名人,最多能拍到的名人数量。但是显然 (mathcal{O(n^2)}) 的朴素 (dp) 过不了此题,所以考虑如何优化此题。看到了一个数据范围 (rle500) 所以可以从这个地方入手,很明显从图上任意一点到另一点的距离,最大也就是 (2r) 所以就可以以此来解题。也就是说只要两个名人之间时间间隔了 (2r) 以上就可以直接用了,所以复杂度就可以降低到 (mathcal{O(nr)}) 这个复杂度是可以接受的。
Code:
#include<bits/stdc++.h>
using namespace std;
inline int read()
{
int x=0,f=1;char c=getchar();
while(c<'0' || c>'9'){if(c=='-') f=0;c=getchar();}
while(c>='0' && c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
return f?x:-x;
}
const int N=1e5+10;
int r,n,t[N],x[N],y[N],f[N],maxn=-0x3f3f3f3f,ans;
int main()
{
r=read(),n=read();
x[0]=y[0]=1;
for(int i=1;i<=n;i++) t[i]=read(),x[i]=read(),y[i]=read();
memset(f,-0x3f,sizeof(f));
f[0]=0;
for(int i=1;i<=n;i++)
{
f[i]=maxn+1;
for(int j=max(i-2*r,0);j<i;j++)
if(abs(x[i]-x[j])+abs(y[i]-y[j])<=t[i]-t[j]) f[i]=max(f[i],f[j]+1);
if(i>=2*r) maxn=max(maxn,f[i-2*r]);
ans=max(ans,f[i]);
}
printf("%d",ans);
return 0;
}