卡牌翻面求和问题 | 豆包MarsCode AI刷题

92 阅读3分钟

大家好,今天我将继续用豆包MarsCode来刷题,今天的题目是卡牌翻面求和问题。

一、题目描述

题目描述了一个卡牌翻面求和的问题,具体如下:

  • 小M有 n 张卡牌,每张卡牌有两个不同的数字,正面是 ai​,背面是 bi​。
  • 小M的目标是通过选择每张卡牌的一面,使得所有选择的数字之和可以被3整除。 image.png

二、解题思路

面对此题还是没有很好的思路,所以让我们看看豆包MarsCode会怎么想

image.png 豆包MarsCode提供的解题思路是利用动态规划(DP)算法解决卡牌翻面求和问题。通过定义一个二维数组 dp[i][j] 来存储前 i 张卡牌在和模3余 j 的情况下,第 i 张卡牌选择正面或背面的方案数。初始化时,dp[0][0] = 1 表示没有卡牌且和为0的方案数为1。对于每张卡牌,根据选择正面或背面更新 dp 数组,通过状态转移方程计算新的和模3的结果。最终,dp[n][0] 给出了前 n 张卡牌和模3余0的方案数。

三、代码解析

不过看了解题思路,我其实还是不是很会做这道题,所以综合了下网上的解题思路,我又让豆包MarsCode接着生成了代码

image.png 对于这段代码我自己试着做了一下解析,其实也就是对每行代码的作用做了一下注释,那这段代码的解析如下所示:

  1. 类和方法定义
    • Main 类包含一个静态方法 solution,该方法接受卡牌数量 n,正面数字数组 a,背面数字数组 b 作为参数。
  2. 常量定义
    • MOD 定义为 1000000007,用于在计算过程中对结果进行取模。
  3. 动态规划数组初始化
    • dp 是一个二维数组,其中 dp[i][j] 表示前 i 张卡牌中,和模3余 j 的方案数。
    • 初始化 dp[0][0] = 1,表示没有卡牌时,和为0的方案数为1。
  4. 状态转移
    • 外层循环遍历每一张卡牌。
    • 内层循环遍历所有可能的和模3的结果(0, 1, 2)。
    • 对于每张卡牌,考虑选择正面或背面,更新 dp 数组。这通过将当前卡牌的正面或背面数字加到和模3的结果上,并从上一张卡牌的方案数中累加得到。
  5. 结果返回
    • 方法返回 dp[n][0],即前 n 张卡牌中,和模3余0的方案数。

四、总结

动态规划是刷题学习过程中一个非常重要的知识点,本题的核心还是在于如何定义状态和状态转移方程,这也是动态规划的核心,将问题分解为更小的子问题,并逐步构建解决方案。但是感觉只看理论的话,可我还是有点做不来类似的题目,面对这种题目还是有种束手无策的感觉,未来的学习计划还是感觉得多学多练。