牛客练习赛59 小松鼠吃松果(优化dp二维偏序)
生活随笔
收集整理的這篇文章主要介紹了
牛客练习赛59 小松鼠吃松果(优化dp二维偏序)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
小松鼠吃松果
非常nicenicenice的一道題
首先考慮dpdpdp
容易想到按照時間來排序
然后定義dp[i]dp[i]dp[i]為考慮前iii個果子且吃掉第iii個的最大價值
那么每次都去前面枚舉一個jjj使得吃完jjj還可以來吃iii
吃完jjj還能吃iii有什么條件呢??
ti?tj>=abs(posi?posj)t_i-t_j>=abs(pos_i-pos_j)ti??tj?>=abs(posi??posj?)
當posi>=posj,ti?posi>=tj?posj當pos_i>=pos_j,t_i-pos_i>=t_j-pos_j當posi?>=posj?,ti??posi?>=tj??posj?
當posi<posj,ti+posi>=tj+posj當pos_i<pos_j,t_i+pos_i>=t_j+pos_j當posi?<posj?,ti?+posi?>=tj?+posj?
用樹狀數(shù)組維護即可
#include <bits/stdc++.h> using namespace std; #define int long long const int maxn=2e5+10; int pos[maxn],b[maxn],ls[maxn],sumn[maxn],n,m; struct node{int t,id,val;bool operator < (const node&tmp ) const{return t==tmp.t?id<tmp.id:t<tmp.t;//優(yōu)先按照x來排序 } }a[maxn]; int lowbit(int x){ return x&(-x); } int query(int x) {int ans=0;for(;x;x-=lowbit(x)) ans = max( ans,sumn[x] );return ans; } void add(int x,int v) {for(;x<=n;x+=lowbit(x)) sumn[x]=max(sumn[x],v); } signed main() {cin >> n >> m;for(int i=1;i<=m;i++) scanf("%d",&pos[i]),ls[i]=pos[i];for(int i=1;i<=m;i++) scanf("%d",&b[i]);for(int i=1;i<=n;i++)scanf("%d%d%d",&a[i].t,&a[i].id,&a[i].val),a[i].t+=b[a[i].id]; for(int i=1;i<=n;i++){int x=a[i].t-pos[a[i].id],y=a[i].t+pos[a[i].id];a[i].t=x,a[i].id=y; ls[i]=y;}sort(ls+1,ls+1+n);sort(a+1,a+1+n);int ans=0; for(int i=1;i<=n;i++){int now=lower_bound(ls+1,ls+1+n,a[i].id)-ls;int dp=query(now)+a[i].val;ans = max( ans,dp );add( now,dp );}cout << ans; }總結(jié)
以上是生活随笔為你收集整理的牛客练习赛59 小松鼠吃松果(优化dp二维偏序)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 逆转是怎么发生的?
- 下一篇: 代码审计工具Fortify 17.10及