Codeforces Global Round 11 C. The Hard Work of Paparazzi
阿新 • • 發佈:2020-11-12
題目連結: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(0View Code); 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 }