大家好,今天我将继续用豆包MarsCode来刷题,今天的题目是卡牌翻面求和问题。
一、题目描述
题目描述了一个卡牌翻面求和的问题,具体如下:
- 小M有 n 张卡牌,每张卡牌有两个不同的数字,正面是 ai,背面是 bi。
- 小M的目标是通过选择每张卡牌的一面,使得所有选择的数字之和可以被3整除。
二、解题思路
面对此题还是没有很好的思路,所以让我们看看豆包MarsCode会怎么想
豆包MarsCode提供的解题思路是利用动态规划(DP)算法解决卡牌翻面求和问题。通过定义一个二维数组
dp[i][j] 来存储前 i 张卡牌在和模3余 j 的情况下,第 i 张卡牌选择正面或背面的方案数。初始化时,dp[0][0] = 1 表示没有卡牌且和为0的方案数为1。对于每张卡牌,根据选择正面或背面更新 dp 数组,通过状态转移方程计算新的和模3的结果。最终,dp[n][0] 给出了前 n 张卡牌和模3余0的方案数。
三、代码解析
不过看了解题思路,我其实还是不是很会做这道题,所以综合了下网上的解题思路,我又让豆包MarsCode接着生成了代码
对于这段代码我自己试着做了一下解析,其实也就是对每行代码的作用做了一下注释,那这段代码的解析如下所示:
- 类和方法定义:
Main类包含一个静态方法solution,该方法接受卡牌数量n,正面数字数组a,背面数字数组b作为参数。
- 常量定义:
MOD定义为1000000007,用于在计算过程中对结果进行取模。
- 动态规划数组初始化:
dp是一个二维数组,其中dp[i][j]表示前i张卡牌中,和模3余j的方案数。- 初始化
dp[0][0] = 1,表示没有卡牌时,和为0的方案数为1。
- 状态转移:
- 外层循环遍历每一张卡牌。
- 内层循环遍历所有可能的和模3的结果(0, 1, 2)。
- 对于每张卡牌,考虑选择正面或背面,更新
dp数组。这通过将当前卡牌的正面或背面数字加到和模3的结果上,并从上一张卡牌的方案数中累加得到。
- 结果返回:
- 方法返回
dp[n][0],即前n张卡牌中,和模3余0的方案数。
- 方法返回
四、总结
动态规划是刷题学习过程中一个非常重要的知识点,本题的核心还是在于如何定义状态和状态转移方程,这也是动态规划的核心,将问题分解为更小的子问题,并逐步构建解决方案。但是感觉只看理论的话,可我还是有点做不来类似的题目,面对这种题目还是有种束手无策的感觉,未来的学习计划还是感觉得多学多练。