K-单调

f[i][j]表示前i个数被恰好分为j个单调区间的最小花费,有f[i][j]=minp=1i1(f[p][j1]+cost[p+1][i]),其中cost[i][j]表示区间[i,j]分成一个单调序列的最小花费。于是问题转化成了求cost;而由题意不难知道这就是上面一道题目(只不过我们还需要求单调下降的情况,这里有个trick,直接将原数列所有数取相反数再求单调上升即可,从答案集合的角度可以知道是正确的)

然而,我们不能在外界循环i,j,然后通过O((ji+1)log(ji+1))的复杂度去算cost[i][j],这样会超时的。我们只能想办法利用之前已经计算过的信息。假设当前计算的是单调上升。我们外层枚举i,然后跑一次左偏树合并,当内层跑到j的时候,假设我们已经计算好了cost[i][i]cost[i][j1],那么对于cost[i][j]来说,我们只用记录最后一段区间的贡献(这个需要记录左偏树的所有节点的权值和),再利用之前已经算好了的cost即可(子问题具有最优性)

需要注意的是,cost应该开三维,最后一维用来记录是单调上升还是单调下降,因为两者计算的时候不应该互相干扰,如果不再开一维的话,可以计算单调上升的时候会用到单调下降的cost,这样肯定就错了

具体见打卡代码

posted @   最爱丁珰  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示