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 }
View Code

 

posted @ 2020-11-12 19:03  canwinfor  阅读(106)  评论(0)    收藏  举报