不写代码了
  • 板块P1714 切蛋糕
  • 楼主AKB48
  • 当前回复25
  • 已保存回复25
  • 发布时间2013/10/3 21:51
  • 上次更新2023/10/22 10:06:09
查看原帖
不写代码了
1187
AKB48楼主2013/10/3 21:51

上完题解就走人(不保证题解正确性)

选定以下字段即可查看[color=red](请各位OIER自我约束!待比赛结束后再查看)[/color]

[color=white]

O(n^2)算法:

设 F(i)为以Ai结尾长度不超过M的最大子序和

对于每个F(i),从1到m枚举k的值,完成Aj的累加和取最大值。

当然这个算法很好写,虽然效率很低。

很显然,这道题可以用堆优化:

用一个二叉堆来维护第i之前的m个前缀和,这样取最小值只要O(1),每个元素插入一次,删除一次,所以总复杂度是O(nlogn)。

最经典的是用队列优化:(在基于前两个算法上)

用s[i]表示前缀和,把i之前m个s[]组成一个队列。在这m个s[]中,如果i<j,且s[i]>s[j]那么s[i]肯定用不到,因为s[i]比s[j]先出队,s[i]又比s[j]大所以肯定用不到它。所以可以把该队列的元素满足:S1<S2<S3<……<Sk(因为不一定有m个元素,所以用k表示)

这样的话取最小值也是O(1)的,每进一个元素从右边开始比较,如果比它大就删掉(满足刚才的性质),当然加了元素之后还要判断是否队列超过m个元素,超过就把左边的删除。摊还分析一下,每个元素进队一次,出队一次,所以总复杂度是O(n)的。

[/color]

如有缺漏,欢迎指出

2013/10/3 21:51
加载中...