【发布时间】:2014-09-09 17:42:28
【问题描述】:
问题:我们有一个大小为n的数组,我们最多可以执行K操作,每个操作都可以
- 将反转次数减少 1。
- 对整个数组进行随机洗牌。
我的问题是执行K 操作,以使最终数组中的预期反转次数最小化。
约束:
100 个带有
的测试用例
1
1
我的方法:我正在考虑动态编程解决方案。我可以使用马洪数计算在大小为n 的数组中恰好有e 反转的概率。我还按行填充数组dp[k+1][1+n(n-1)/2],这样dp[i][j] 表示在执行i 操作之后具有j 反转的数组中的最小预期反转然后使用它我可以生成@987654331 的最小预期值数组中所有可能的反转的@操作。
由于 c++ 中双精度数的限制,这种方法的问题是概率不准确,并且该算法对于每个测试用例都是 O(kn<sup>2</sup>),这非常慢。
例如:
在大小为 100 的数组中没有反转的概率 = 1.0/factorial(100) ~ 10<sup>-160</sup>(我认为这里缺乏精度)。
我认为有一些准确和更有效的方法。请提出一些想法。
谢谢
【问题讨论】:
-
对于操作 #2,您的意思是对连续子数组进行随机洗牌,即索引在 i 和 j 之间的所有元素的子数组,其中 1
-
@user2566092 是整个数组的随机洗牌
-
@userDD 实际上我认为如果数组很大并且操作次数很少我错了,那么最好保持随机改组数组,直到你得到足够低的反转次数机会,然后一旦你这样做了,你就可以通过将其余操作的反转次数减少 1 来完成。
-
@user2566092 在第一步中,我们可以将反转次数减少到 min(n(n-1)/4,currentInvCount - 1 ),但是在 k 次操作之后我们不能做任何事情。
-
@btilly 你是对的; this problem 来自 2014 年 9 月的同一场比赛。一旦这条评论在首屏可见,我将删除另一条评论。
标签: c++ algorithm mathematical-optimization inversion expectations