青训营X豆包MarsCode 技术训练营第一课 | 豆包MarsCode AI 刷题

57 阅读2分钟

第66题魔法甜点之和:小包的新挑战 这道题的思路历程是这样的: 小R的目标是通过选择一些甜点,可能使用魔法棒,使得这些甜点的喜爱值之和恰好为 S。每个甜点有一个固定的喜爱值,使用魔法棒可以将甜点的喜爱值变为原来喜爱值的阶乘。每个甜点只能使用一次魔法棒,也可以完全不用。 定义状态: 我们使用一个三维数组 dp[i][j][k],其中 i 表示前 i 个甜点,j 表示使用了 j 个魔法棒,k 表示当前的喜爱值之和。dp[i][j][k] 表示在前 i 个甜点中,使用 j 个魔法棒时,喜爱值之和为 k 的方案数。 初始化: dp[0][0][0] = 1,表示不选择任何甜点,不使用任何魔法棒,喜爱值之和为 0 的方案数为 1。 状态转移: 对于每个甜点 like[i-1],我们有两种选择: 不使用魔法棒:直接将当前甜点的喜爱值加入到之前的所有可能的喜爱值之和中。 使用魔法棒:将当前甜点的喜爱值的阶乘加入到之前的所有可能的喜爱值之和中。 具体的状态转移方程如下: 不使用魔法棒:dp[i][j][k] += dp[i-1][j][k - like[i-1]](如果 k >= like[i-1]) 使用魔法棒:dp[i][j][k] += dp[i-1][j-1][k - factorial(like[i-1])](如果 j > 0 且 k >= factorial(like[i-1])) 结果: 最终的结果是 dp[n][m][S],即在前 n 个甜点中,使用 m 个魔法棒时,喜爱值之和为 S 的方案数。 总结 通过上述详细的动态规划思路,我们可以有效地计算出所有可能的组合,并统计满足条件的组合数。这个方法的时间复杂度为 O(n * m * S),其中 S 是目标喜爱值之和。 知识点如下: 动态规划(Dynamic Programming):

使用三维数组 dp 来存储子问题的解,从而避免重复计算。 通过状态转移方程来更新 dp 数组中的值。 阶乘计算:

定义了一个 factorial 函数来计算一个数的阶乘。 在动态规划的状态转移过程中,使用了阶乘的结果。 嵌套循环:

使用三层嵌套循环来遍历所有可能的情况,即甜点的数量、魔法棒的数量以及喜爱值之和。 条件判断:

在状态转移过程中,通过条件判断来决定是否使用魔法棒。