1. 程式人生 > 實用技巧 >Codeforces Global Round 11 C. The Hard Work of Paparazzi

Codeforces Global Round 11 C. The Hard Work of Paparazzi

題目連結: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 using namespace std;
 3 #define ll long long
 4 #define pb push_back
 5 const int mod=1e9+7;
 6 const int maxn=1e5+10;
 7 int dp[maxn];
 8 int pre[maxn];
 9 
10 struct ac
11 {
12     int t,x,y;
13 };
14 ac a[maxn];
15 
16 
17 
18 
19 int main()
20 {
21     ios::sync_with_stdio(0
); 22 cin.tie(0); 23 int r,n; 24 cin>>r>>n; 25 for(int i=1;i<=n;i++) 26 { 27 cin>>a[i].t>>a[i].x>>a[i].y; 28 } 29 a[0].x=a[0].y=1; 30 int ans=0; 31 for(int i=1;i<maxn;i++) 32 dp[i]=-1e9; 33 dp[0]=0; 34 for(int i=1
;i<=n;i++) 35 { 36 if(i>1000) 37 dp[i]=pre[i-1000]+1; 38 int cnt=0; 39 for(int j=max(0,i-1000);j<i;j++) 40 { 41 int temp=abs(a[i].x-a[j].x)+abs(a[i].y-a[j].y); 42 if(temp<=a[i].t-a[j].t) 43 { 44 dp[i]=max(dp[i],dp[j]+1); 45 } 46 cnt=max(cnt,dp[i]); 47 } 48 ans=max(ans,dp[i]); 49 pre[i]=max(pre[i-1],cnt); 50 } 51 /*for(int i=1;i<=4;i++) 52 cout<<dp[i]<<'\n';*/ 53 cout<<ans<<'\n'; 54 }
View Code