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 @   最爱丁珰  阅读(3)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
点击右上角即可分享
微信分享提示