Codeforces Global Round 11 C. The Hard Work of Paparazzi ###K ###K //K
题目链接:https://codeforces.ml/contest/1427/problem/C
题意:给定一个矩形,n个人会出现在某个时刻 刚开始在1,1 问能碰到的最多的人是多少 每个出现的人的时间是单调递增的
思路:因为没法直接考虑怎么找才能找最多的人 所以考虑dp 来得到所有状态
dp[i] 为 到达第i个人 时能碰到的最多人 那么转移方程就为dp[i]=max(dp[i],dp[j]+1) 满足dis<=时间差的时候
但是这样的话是o(n^2) 题目给了r=500 所以考虑通过r来降低时间复杂度 因为当时间差超过1000的时候 可以从
任何一个点到其他的任意一个点上,所以第二层循环最多只需要枚举1000个点即可 用一个pre[] 数组来记录 到第i个人为止的最大值
注意是因每个时间点只有一个人出现 且时间是单调递增的才有这样的性质
1 #include <bits/stdc++.h> 2 #define double long double 3 #define lb long double 4 #define ll long long 5 #define pi pair<int,int> 6 #define fi first 7 #define sc second 8 #define pb push_back 9 using namespace std; 10 const int maxn=1e5+10; 11 const int mod=1e9+7; 12 13 14 struct ac 15 { 16 int t,x,y; 17 }; 18 ac a[maxn]; 19 int r,n; 20 int dp[maxn],mx[maxn]; 21 22 23 int main() 24 { 25 ios::sync_with_stdio(0); 26 cin.tie(0); 27 cin>>r>>n; 28 for(int i=1;i<=n;i++) 29 { 30 cin>>a[i].t>>a[i].x>>a[i].y; 31 } 32 memset(dp,-0x3f,sizeof(dp)); 33 dp[0]=0; 34 a[0]={0,1,1}; 35 for(int i=1;i<=n;i++) 36 { 37 if(i>=1000) dp[i]=mx[i-1000]+1; 38 for(int j=max(0,i-1000);j<i;j++) 39 { 40 int tmp=abs(a[i].x-a[j].x)+abs(a[i].y-a[j].y); 41 int ti=a[i].t-a[j].t; 42 if(ti>=tmp) 43 { 44 dp[i]=max(dp[i],dp[j]+1); 45 } 46 } 47 mx[i]=max(mx[i-1],dp[i]); 48 } 49 cout<<mx[n]<<'\n'; 50 51 52 53 54 55 56 57 }

浙公网安备 33010602011771号