欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

P3287-[SCOI2014]方伯伯的玉米田【二维树状数组,dp】

发布时间:2023/12/3 编程问答 50 豆豆
生活随笔 收集整理的这篇文章主要介绍了 P3287-[SCOI2014]方伯伯的玉米田【二维树状数组,dp】 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

正题

题目链接:https://www.luogu.com.cn/problem/P3287


题目大意

nnn个玉米高度不同,可以选择kkk个区间拔高111个高度,求最长不降子序列长度。


解题思路

显然每次拔高都是拔一个后缀,所以我们设fi,jf_{i,j}fi,j表示到第iii个玉米,拔到现在包含了jjj个拔高的后缀时的最大答案。
fi,j=max{fh,k}(ai+j≥ah+k,j≥k)f_{i,j}=max\{f_{h,k}\}(a_i+j\geq a_h+k,j\geq k)fi,j=max{fh,k}(ai+jah+k,jk)

用二维树状数组维护一下即可

时间复杂度O(nklog⁡(ai+k)log⁡k)O(\ nk\log(a_i+k)\log k\ )O( nklog(ai+k)logk )


codecodecode

#include<cstdio> #include<cstring> #include<algorithm> #define lowbit(x) (x&-x) using namespace std; const int N=11000; int n,k,a[N],t[510][5600],f[N][510]; void Change(int x,int y,int val){for(int i=x;i<=k;i+=lowbit(i))for(int j=y;j<=5500;j+=lowbit(j))t[i][j]=max(val,t[i][j]);return; } int Ask(int x,int y){int ans=0;for(int i=x;i;i-=lowbit(i))for(int j=y;j;j-=lowbit(j))ans=max(ans,t[i][j]);return ans; } int main() {scanf("%d%d",&n,&k);int ans=0;k++;for(int i=1;i<=n;i++){scanf("%d",&a[i]); for(int j=k;j>=1;j--){f[i][j]=Ask(j,a[i]+j)+1;Change(j,a[i]+j,f[i][j]);ans=max(ans,f[i][j]);}}printf("%d",ans); }

总结

以上是生活随笔为你收集整理的P3287-[SCOI2014]方伯伯的玉米田【二维树状数组,dp】的全部内容,希望文章能够帮你解决所遇到的问题。

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