最小周长巧克力板组合 | 豆包MarsCode AI刷题

106 阅读2分钟

问题理解

  1. 目标:将整数 n 分解成若干个正方形的面积和,使得这些正方形的总周长最小。
  2. 周长计算:每个正方形的周长是其边长的四倍。

数据结构选择

  1. 动态规划:我们可以使用动态规划来记录每个可能的 n 的最小周长。
  2. 贪心算法:从最大的正方形开始分解 n,逐步减小正方形的边长,直到 n 被完全分解。

算法步骤

  1. 初始化:创建一个数组 dp,其中 dp[i] 表示将 i 分解成若干正方形的最小周长。
  2. 状态转移:对于每个 i,尝试将其分解成一个正方形和剩余部分的最小周长之和。
  3. 边界条件dp[0] = 0,因为面积为0的正方形周长为0。

具体步骤

  1. 遍历:从 1 到 n,对于每个 i,尝试将其分解成一个正方形和剩余部分的最小周长之和。
  2. 更新:对于每个 i,尝试所有可能的正方形边长 j(从 1 到 sqrt(i)),更新 dp[i] 为 dp[i - j*j] + 4*j 的最小值。
public class Main {
    public static int solution(int n) {
        // dp[i] 表示将整数 i 分解成若干个正方形面积和时的最小周长
        int[] dp = new int[n + 1];
        
        // 初始化 dp 数组
        for (int i = 1; i <= n; i++) {
            dp[i] = i * 4; // 最坏情况下每个正方形的边长为1
        }
        
        // 动态规划求解
        for (int i = 1; i <= n; i++) {
            for (int k = 1; k * k <= i; k++) {
                dp[i] = Math.min(dp[i], dp[i - k * k] + 4 * k);
            }
        }
        
        return dp[n];
    }

    public static void main(String[] args) {
        System.out.println(solution(11) == 20);
        System.out.println(solution(13) == 20);
        System.out.println(solution(25) == 20);
    }
}

关键步骤解释

  1. 初始化 dp 数组

    • dp[i] 初始化为 i * 4,表示最坏情况下每个正方形的边长为1。
  2. 动态规划求解

    • 对于每个 i,尝试将其分解成一个边长为 k 的正方形和剩余部分的最小周长之和。
    • 更新 dp[i] 为 dp[i - k * k] + 4 * k 的最小值。

代码提示

  • 初始化 dp 数组:确保每个 dp[i] 在最坏情况下都被正确初始化。
  • 动态规划更新:使用双重循环来更新 dp 数组,确保每个 i 都被正确分解。

思路总结

  1. 初始化:将 dp 数组初始化为最坏情况,即每个正方形的边长为1。
  2. 动态规划:通过双重循环,逐步更新 dp 数组,确保每个 i 都被正确分解。
  3. 返回结果:最终 dp[n] 即为所求的最小周长。