SCOI2014 方伯伯的玉米田 题解

可能其它还没写完的几篇随笔要搁一会儿,反正先写写题解

\(1-n\)的一个序列,值分别为\(a[1]\)\(a[2]...a[n]\),最多可进行\(K\)次操作,每次操作可以使\(l-r\)区间内的所有元素值加一(\(l\)\(r\)自选)。操作完后,还可以删除任意多个元素(不需要连续),使剩下的元素构成一个不下降序列,问这个子序列最多有多少个元素

首先,经过初步思考与推测可以得出一个结论,就是每次操作的区间中\(r\)一定为\(n\),因为最终要构成的是一个不下降的子序列,所以若\(r\neq n\),那么后面的元素相对于前面的元素就会下降多个单位,最终导致低于前面的元素而被删除,所以剩下的元素也会相应减少,不满足最优的条件

有了这个性质以后,我们便可以设\(dp[i][j]\)表示前\(i\)个元素共计被加了\(j\)次后构成的最后一个元素的下标为\(i\)为最长不下降子序列的长度(为什么\(i\)一定要选?因为若是不选那么我们就不知道当前序列最后一个元素是什么,然后就无法在转移时比较高度来构成不下降序列了),那么显然,第\(i\)个元素一定被加了\(j\)次,所以其高度为\(a[i]+j\)

接下来状态转移,首先二重循环枚举\(i\)\(j\)少不了,然后再枚举\(k\)\(p\),表示要从\(dp[k][p]\)这个状态转移过来(相当于\(i+1-k-1\)的元素都被删掉了),所以我们有如下的状态转移方程:

\(dp[i][j]=max\left\{dp[k][p]+1\right\},a[k]+p \le a[i]+j,p \le j,k<i\)

不幸的是,这样转移的复杂度是\(O(n^2k^2)\)的,实在是难以接受,所以还是要优化一下。发现我们每次只是在满足\(a[k]+p \le a[i]+j,p \le j,k<i\)的情况下找到一个最大的\(dp[k][p]+1\)并更新当前状态,然后再用这个状态更新之后的状态,有些像线段树的单点查询与修改,但是仅仅是这两个操作我们就不一定要用线段树了,树状数组也可以实现,而且无论在码长还是在常数上都比线段树优秀,所以最终选用树状数组优化

猜你喜欢

转载自www.cnblogs.com/ForwardFuture/p/9272989.html
今日推荐