小Y准备购买一些基金,记录本 arr 中记录了每个基金的期望值,期望值可能为负数,表示小Y不喜欢这个基金。她可以进行至多 k k 次操作,每次操作包括: 购买最左边的基金,并将其从记录本中删除。 购买最右边的基金,并将其从记录本中删除。 卖掉她持有的某个基金,并将它记录在记录本的最左边。 卖掉她持有的某个基金,并将它记录在记录本的最右边。 小Y希望通过这些操作使得她最终持有的基金期望值之和尽可能大。
-
初始化动态规划相关数据结构:
- 首先获取输入基金期望值列表
arr的长度n,然后创建一个二维列表dp,用于存储动态规划过程中的中间结果。dp的行数为n + 1,列数为k + 1,其中dp[i][j]表示在前i个基金中进行了j次操作后能获得的最大期望值之和,初始值都设为负无穷大(-float('inf')),表示初始状态下还未进行任何操作,没有有效的期望值之和,同时将dp[0][0]设置为 0,表示没有基金且没有进行操作时,期望值之和为 0,作为动态规划的初始状态。
- 首先获取输入基金期望值列表
-
动态规划递推计算最大期望值之和:
-
通过两层嵌套的循环来进行动态规划的递推计算。外层循环控制考虑的基金数量
i,范围从 1 到n,表示逐步增加可选择的基金数量来进行操作和计算最大期望值之和。内层循环控制操作次数j,范围从 0 到min(i, k + 1),因为操作次数不能超过基金数量i且最多为给定的k次,所以取两者中的较小值,对于每一个i和j的组合,考虑以下几种操作情况来更新dp[i][j]的值:- 选择最左边的基金:如果操作次数
j大于等于 1(表示至少进行了一次操作),那么可以选择购买最左边的基金,此时的最大期望值之和就是在前i - 1个基金中进行了j - 1次操作后的最大期望值之和dp[i - 1][j - 1]再加上当前最左边基金的期望值arr[i - 1],通过max函数取这个值与当前dp[i][j]的较大值来更新dp[i][j],即dp[i][j] = max(dp[i][j], dp[i - 1][j - 1] + arr[i - 1])。 - 选择最右边的基金:同样,如果
j大于等于 1,可以选择购买最右边的基金,此时最大期望值之和就是在前i - 1个基金中进行了j - 1次操作后的最大期望值之和dp[i - 1][j - 1]再加上当前最右边基金的期望值arr[n - (i - 1)](通过n - (i - 1)来获取最右边基金在原列表中的索引),使用max函数取较大值更新dp[i][j],即dp[i][j] = max(dp[i][j], dp[i - 1][j - 1] + arr[n - (i - 1)])。 - 卖掉持有的某个基金放在最左边:通过一个内层循环遍历可能的卖掉操作次数
m,范围从 1 到j + 1(因为卖掉操作次数不能超过总的操作次数j),对于每一个m,表示卖掉m次持有的基金并放在最左边的情况,此时最大期望值之和就是在前i - 1个基金中进行了j - m次操作后的最大期望值之和dp[i - 1][j - m]再加上当前最左边基金的期望值arr[i - 1](相当于重新把它加入到持有的基金中),同样使用max函数取较大值更新dp[i][j],即dp[i][j] = max(dp[i][j], dp[i - 1][j - m] + arr[i - 1])。 - 卖掉持有的某个基金放在最右边:类似地,通过另一个内层循环遍历
m(范围同样从 1 到j + 1),表示卖掉m次持有的基金并放在最右边的情况,此时最大期望值之和就是在前i - 1个基金中进行了j - m次操作后的最大期望值之和dp[i - 1][j - m]再加上当前最右边基金的期望值arr[n - (i - 1)],使用max函数取较大值更新dp[i][j],即dp[i][j] = max(dp[i][j], dp[i - 1][j - m] + arr[n - (i - 1)])。
- 选择最左边的基金:如果操作次数
-
-
返回最终结果:
-
当两层嵌套循环结束后,
dp列表的最后一行(索引为n)中存储了在所有n个基金中进行不同操作次数后的最大期望值之和,通过max(dp[n])取出这一行中的最大值,它就是经过至多k次操作后最终持有的基金期望值之和的最大值,将其返回即可。
-
时间复杂度方面,外层循环遍历基金数量 i 的时间复杂度为 (n 为基金数量),内层循环控制操作次数 j 的时间复杂度为 ,而对于每次 j 的循环中,又包含了两个时间复杂度为 的内层循环(用于卖掉操作的情况),所以整体时间复杂度大致为 ,在处理常规数量的基金以及给定的操作次数时能够通过动态规划的方式正确地计算出最大期望值之和。