P2285打鼹鼠-题解
基础的DP各位大佬已经讲得很明白了,本文主要讲一讲优化
DP状态很容易想到:
转移:
重点来了!!
优化
我们发现,如果时间差大于 天涯海角哪里都能走到,又因为输入的时间是升序排列,我们只需要在转移时维护
#include<bits/stdc++.h>
using namespace std;
int t[10010],x[10010],y[10010];
int f[10010],g[10010];
int dis(int a,int b) {
return abs(x[a]-x[b])+abs(y[a]-y[b]);
}
int main() {
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
scanf("%d%d%d",&t[i],&x[i],&y[i]);
for(int i=1;i<=m;i++) {
int start=max(0,int(upper_bound(t+1,t+i,t[i]-2*n)-t-1));
f[i]=g[start]+1;
for(int j=max(1,start);j<i;j++) {
if(t[i]-t[j]>=dis(i,j))
f[i]=max(f[i],f[j]+1);
}
g[i]=max(g[i-1],f[i]);
}
printf("%d\n",g[m]);
return 0;
}
哎哎哎,别急着走,后面还有:
继续优化
我们发现,由于时间是递增的,所以
#include<bits/stdc++.h>
using namespace std;
int t[10010],x[10010],y[10010];
int f[10010],g[10010],start[10010];
int dis(int a,int b) {
return abs(x[a]-x[b])+abs(y[a]-y[b]);
}
int main() {
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
scanf("%d%d%d",&t[i],&x[i],&y[i]);
for(int i=1;i<=m;i++) {
start[i]=max(0,int(upper_bound(t+start[i-1],t+i,t[i]-2*n)-t-1));
f[i]=g[start[i]]+1;
for(int j=max(1,start[i]);j<i;j++) {
if(t[i]-t[j]>=dis(i,j))
f[i]=max(f[i],f[j]+1);
}
g[i]=max(g[i-1],f[i]);
}
printf("%d\n",g[m]);
return 0;
}
哎哎哎,别急着走,后面还有:
继续继续优化
我们甚至可以直接不用
for(;t[i]-t[start+1]>=2*n;start++);
来更新
最终代码:
#include<bits/stdc++.h>
using namespace std;
int t[10010],x[10010],y[10010];
int f[10010],g[10010],start;
int dis(int a,int b) {
return abs(x[a]-x[b])+abs(y[a]-y[b]);
}
int main() {
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
scanf("%d%d%d",&t[i],&x[i],&y[i]);
for(int i=1;i<=m;i++) {
for(;t[i]-t[start+1]>=2*n;start++);
f[i]=g[start]+1;
for(int j=max(1,start);j<i;j++) {
if(t[i]-t[j]>=dis(i,j))
f[i]=max(f[i],f[j]+1);
}
g[i]=max(g[i-1],f[i]);
}
printf("%d\n",g[m]);
return 0;
}
不开O2可达48ms,可见优化非常显著。
请勿抄袭,如果一定要抄,请理解明白后再抄
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步