【洛谷】P7302 [NOI1998] 免费的馅饼(数据结构优化dp)
题意
SERKOI 最新推出了一种叫做“免费馅饼”的游戏:游戏在一个舞台上进行。舞台的宽度为 格(从左到右依次用 到 编号),游戏者占一格。开始时游戏者可以站在舞台的任意位置,手里拿着一个托盘。
游戏开始后,从舞台天幕顶端的格子中不断出现馅饼并垂直下落。游戏者左右移动去接馅饼。游戏者每秒可以向左或向右移动一格或两格,也可以站在原地不动。
当馅饼在某一时刻恰好到达游戏者所在的格子中,游戏者就收集到了这块馅饼。当馅饼落在一个游戏者不在的格子里时该馅饼就消失。
写一个程序,帮助我们的游戏者收集馅饼,使得所收集馅饼的分数之和最大。
数据范围
,,,,。
思路
题目中给的舞台宽度很大,但是总的馅饼数很少。考虑按照馅饼进行 dp。
设 表示捡起第 个馅饼时获得的最大分数。根据题意,易得状态转移方程:
,其中 和 满足 。
朴素的转移时间复杂度为 。由于不等式中带了绝对值,不方便进行优化, 不妨先去掉绝对值,得到:
显然可以通过排序的方式使转移时其中一个不等式恒成立,我们不妨按照 从大到小排序。那么此时因为无法判断 和 大小关系,转移时仍需满足另一个不等式(因为满足最原始的不等式的决策点一定满足另一个不等式)。
注意到满足另一个不等式的是一个区间内的决策点,那么就可以先将 离散化,用树状数组维护区间最大值。时间复杂度为 。
code:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1e5+10;
int w,n,num[N],tot,c[N];
struct node{int t,p,l,r,v;bool operator <(const node &tmp)const{return l>tmp.l;}}a[N];
int lowbit(int x){return x&-x;}
void update(int x,int k){while(x<=tot){c[x]=max(c[x],k);x+=lowbit(x);}}
int query(int x){int res=0;while(x){res=max(res,c[x]);x-=lowbit(x);}return res;}
int main()
{
scanf("%d%d",&w,&n);
for(int i=1;i<=n;i++)
{
scanf("%d%d%d",&a[i].t,&a[i].p,&a[i].v);
a[i].l=a[i].p-2*a[i].t;a[i].r=a[i].p+2*a[i].t;num[i]=a[i].r;
}
sort(a+1,a+n+1);sort(num+1,num+n+1);tot=unique(num+1,num+n+1)-num-1;
for(int i=1;i<=n;i++) a[i].r=lower_bound(num+1,num+tot+1,a[i].r)-num;
for(int i=1;i<=n;i++) update(a[i].r,query(a[i].r)+a[i].v);
printf("%d\n",query(tot));
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!