CodeForces - 1427C - The Hard Work of Paparazzi dp
题意:给出n个点
(
x
i
,
y
i
)
(x_i,y_i)
(xi,yi),如果主人公在
t
i
t_i
ti在这个点上,就可以拍照,从一个点到另一个点的花费时间是两点的曼哈顿距离。
想不出来 又是抄的题解
dp状态:
d
p
[
i
]
dp[i]
dp[i]表示
[
1
,
i
]
[1,i]
[1,i]个点最多可以拍多少照片
初始化:
d
p
[
0
]
=
0
,
d
p
[
i
]
=
dp[0]=0,dp[i]=
dp[0]=0,dp[i]=负无穷
思路:(假设
i
<
j
i<j
i<j)
如果曼哈顿距离
∣
x
i
−
x
j
∣
+
∣
y
i
−
y
j
∣
≤
t
i
−
t
j
|x_i-x_j|+|y_i-y_j| \leq t_i-t_j
∣xi−xj∣+∣yi−yj∣≤ti−tj,就说明从
j
j
j点到
i
i
i点拍照是可能的。如果
n
2
n^2
n2暴力dp,显然不行
根据矩形性质,可以得到
∣
x
i
−
x
j
∣
+
∣
y
i
−
y
j
∣
≤
2
r
|x_i-x_j|+|y_i-y_j| \leq 2r
∣xi−xj∣+∣yi−yj∣≤2r
当
2
r
≤
t
i
−
t
j
2r \leq t_i-t_j
2r≤ti−tj时,
∣
x
i
−
x
j
∣
+
∣
y
i
−
y
j
∣
≤
2
r
≤
t
i
−
t
j
|x_i-x_j|+|y_i-y_j|\leq 2r \leq t_i-t_j
∣xi−xj∣+∣yi−yj∣≤2r≤ti−tj恒成立,满足这个条件的
i
,
j
i,j
i,j可达。
由于 t j < t i t_j<t_i tj<ti恒成立,所以 i − j ≤ t i − t j i-j \leq t_i-t_j i−j≤ti−tj
将 j j j分为两段:
- 当 2 r ≤ i − j 2r\leq i-j 2r≤i−j时, ∣ x i − x j ∣ + ∣ y i − y j ∣ ≤ 2 r ≤ i − j ≤ t i − t j |x_i-x_j|+|y_i-y_j|\leq 2r \leq i-j \leq t_i-t_j ∣xi−xj∣+∣yi−yj∣≤2r≤i−j≤ti−tj,对于这些 j < i j<i j<i,与 i i i是可达的,所以可以进行状态转移,但是这样的 j j j显然有很多个,可以用一个前缀数组记录下最大值,转移一次即可。
- 当 i − 2 r < j i-2r<j i−2r<j时, ∣ x i − x j ∣ + ∣ y i − y j ∣ ≤ t i − t j |x_i-x_j|+|y_i-y_j| \leq t_i-t_j ∣xi−xj∣+∣yi−yj∣≤ti−tj不一定成立,所以要逐个判断,但是最多只有 2 r 2r 2r个 j j j,所以复杂度是 O ( 2 n r ) O(2nr) O(2nr)
代码:
const int maxn=2e6+7;
const int INF=0x3f3f3f3f;
const ll INFF=1e18;
int r,n,t[maxn],x[maxn],y[maxn],dp[maxn],ans=0,maxx[maxn];
int main()
{
scanf("%d%d",&r,&n);
rep(i,1,n)scanf("%d%d%d",&t[i],&x[i],&y[i]),dp[i]=maxx[i]=-INF;
x[0]=1,y[0]=1;
dp[0]=maxx[0]=0;
rep(i,1,n)
{
if (i>=2*r)dp[i]=maxx[i-2*r]+1;//j from[0,max(0,i-2r-1)]
for (int j=i-1;j>=max(0,i-2*r);j--)//j from[max(0,i-2r),i-1]
{
if (abs(x[i]-x[j])+abs(y[i]-y[j])<=t[i]-t[j])dp[i]=max(dp[i],dp[j]+1);
}
maxx[i]=max(maxx[i-1],dp[i]);
}
W(maxx[n]);
return 0;
}