1400E. Clear the Multiset(决策取优,或叫分治?)
发布日期:2021-06-30 10:20:43 浏览次数:3 分类:技术文章

本文共 1510 字,大约阅读时间需要 5 分钟。

想象一下假如进行操作1,怎样是比较优秀的

即 为 : 对 于 [ L , R ] 一 段 连 续 不 为 0 的 数 字 , 设 m i n n 为 其 中 最 小 的 数 字 即为:对于[L,R]一段连续不为0的数字,设minn为其中最小的数字 :[L,R]0,minn

怎 样 操 作 是 最 少 的 ? 怎样操作是最少的? ?

决 策 1 : 这 段 数 字 如 果 不 进 行 操 作 1 , 那 么 答 案 是 R − L + 1 \color{Red}决策1:这段数字如果不进行操作1,那么答案是R-L+1 1:1,RL+1

决 策 2 : 若 进 行 操 作 1 , 至 少 进 行 m i n n 次 ( 否 则 没 有 一 个 元 素 变 成 0 , 无 意 义 ) \color{Red}决策2:若进行操作1,至少进行minn次(否则没有一个元素变成0,无意义) 2:1,minn(0,)

而 且 这 m i n n 次 贪 心 的 从 L 操 作 到 R , 元 素 的 减 少 只 会 对 后 续 更 优 而且这minn次贪心的从L操作到R,元素的减少只会对后续更优 minnLR,

那 么 经 过 这 m i n n 次 后 , [ L , R ] 分 成 若 干 个 连 续 不 为 0 的 子 段 那么经过这minn次后,[L,R]分成若干个连续不为0的子段 minn,[L,R]0

我 们 发 现 这 也 是 相 同 的 子 问 题 , 对 这 些 子 段 进 行 相 同 操 作 递 归 就 好 了 我们发现这也是相同的子问题,对这些子段进行相同操作递归就好了 ,

所以最后,消除[L,R]就是在决策1和决策2中取小

#include 
using namespace std;const int maxn=5009;int n,a[maxn];int dfs(int l,int r){ if( l==r ) return a[l]!=0; int minn=1e9+1; for(int i=l;i<=r;i++) minn=min(minn,a[i]);//找到最小元素 int last=0,ans=minn; for(int i=l;i<=r;i++) { a[i]-=minn;//清空 if( last==0&&a[i] ) last=i; if( a[i]==0&&last ) ans+=dfs(last,i-1),last=0;//last到i-1就是连续不为0的子段 } if( a[r]!=0 ) ans+=dfs(last,r); return min( ans,r-l+1 );//决策取小 }int main(){ cin >> n; int last=0,ans=0; for(int i=1;i<=n;i++) cin >> a[i]; for(int i=1;i<=n;i++) { if( last==0&&a[i] ) last=i; if( a[i]==0&&last ) ans+=dfs(last,i-1),last=0; } if( a[n]!=0 ) ans+=dfs(last,n); cout << ans;}

转载地址:https://issue-is-vegetable.blog.csdn.net/article/details/108232140 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:1400B. RPG Protagonist(贪心枚举)
下一篇:1400D. Zigzags(dp转移emm)

发表评论

最新留言

网站不错 人气很旺了 加油
[***.192.178.218]2024年04月18日 09时15分14秒