欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

牛客练习赛59 小松鼠吃松果(优化dp二维偏序)

发布时间:2023/12/9 59 豆豆
生活随笔 收集整理的这篇文章主要介绍了 牛客练习赛59 小松鼠吃松果(优化dp二维偏序) 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

小松鼠吃松果

非常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)titj>=abs(posiposj)

当posi>=posj,ti−posi>=tj−posj当pos_i>=pos_j,t_i-pos_i>=t_j-pos_jposi>=posj,tiposi>=tjposj

当posi<posj,ti+posi>=tj+posj当pos_i<pos_j,t_i+pos_i>=t_j+pos_jposi<posj,ti+posi>=tj+posj

用树状数组维护即可

#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;//优先按照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; }

总结

以上是生活随笔为你收集整理的牛客练习赛59 小松鼠吃松果(优化dp二维偏序)的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。