洛谷 P3287 [SCOI2014] 方伯伯的玉米田 题解
题目大意
给定一个长度为 的序列 ,可以进行最多 次操作,每次操作可以选择一个区间加 。
求操作之后最长的最长不降升子序列长度。
,,。
题目解析
要让最长不降升子序列最长,那么显然要让后面的数更大,所以每次操作的右端点选择 肯定不劣。
设 为前 个 LIS 为 ,使用了 次操作的最长 LIS 长度。
假设从 转移,如果 ,直接转移,否则使用操作把 变成和 一样大即可。
朴素刷表转移为 。
考虑优化。
第一种转移,转移前后的 相同,每次从更小或者相同的 转移,对于每个 维护 。
第二种转移,转移前后的 相同,每次从更小或者相同的 转移,对于每个 维护
开若干个树状数组维护前缀最大值即可。
时间复杂度 。
#define maxn 10039 int n,m,k,a[maxn],f[maxn][539],ans; class BIT{ public: #define lowbit(x) (x&-x) int c[5539]; int query(int x){ int s=-1; while(x) s=mmax(s,c[x]),x-=lowbit(x); return s; } void add(int x,int y){ while(x<=m) c[x]=mmax(c[x],y),x+=lowbit(x); return; } }lo[539],ov[5539],sum; int main(){ fin>>n>>k; int i,j; for(i=1;i<=n;i++) fin>>a[i],m=mmax(a[i],m); for(i=1;i<=n;i++) for(j=0;j<=k;j++){ f[i][j]=mmax(lo[j].query(a[i]),ov[a[i]+j].query(j+1))+1; ans=mmax(ans,f[i][j]); lo[j].add(a[i],f[i][j]); ov[a[i]+j].add(j+1,f[i][j]); } fin<<ans<<'\n'; return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
2022-10-27 CSP 2022 S2 游记
2021-10-27 CSP2021S2T1 廊桥分配 题解
2021-10-27 关于 C++ STL 的用法(部分,自行备忘)