leetcode刷题第十三天

本文探讨了爬楼梯问题与打家劫舍问题的解决方案,通过递推关系和动态规划方法来求解不同场景下的最优解。具体包括递归公式、状态转移方程及其实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第十三天

70 爬楼梯

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 12 个台阶。你有多少种不同的方法可以爬到楼顶呢?

基本方法

考虑到达最后一级阶梯的方法数,有两种方式,一种是直接一步跨两级阶梯,另外一种是一步跨一级。

因此,如果将爬n级阶梯得总方法数记为f(n),那么根据加法原理,存在以下递推关系:
f(n)=f(n−1)+f(n−2) f(n)=f(n-1)+f(n-2) f(n)=f(n1)+f(n2)
由于原题数据量较小,可以考虑直接打表即可。

class Solution {
    public int climbStairs(int n) {
        int[] res = {1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368,75025,121393,196418,317811,514229,832040,1346269,2178309,3524578,5702887,9227465,14930352,24157817,39088169,63245986,102334155,165580141,267914296,433494437,701408733,1134903170,1836311903};
        return res[n - 1];
    }
}
矩阵快速幂

依据递推关系式,可以得到
$$
\left{
\begin{array}{lr}
f(n+1)=f(n)+f(n-1)\
f(n)=f(n)
\end{array}

\right.
因此,可以得出以下矩阵关系: 因此,可以得出以下矩阵关系:
\begin{bmatrix}
f(n+1)\
f(n)
\end{bmatrix}

\begin{bmatrix}
1 & 1\
1 & 0
\end{bmatrix}
\begin{bmatrix}
f(n)\
f(n-1)
\end{bmatrix}

\begin{bmatrix}
1 & 1\
1 & 0
\end{bmatrix}^n
\begin{bmatrix}
f(1)\
f(0)
\end{bmatrix}
$$


198 打家劫舍

你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警

给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。

方法

考虑到第i间房间为止,能够偷到的最大数量的金额。**定义dp[i]表示小偷从第0间房间开始偷,偷到第i间房间能够偷到的最大金额。**那么对于第i间房间,存在两种情况:

  • 偷第i间房间
  • 不偷第i间房间

对于第一种情况,如果偷了第i间房间,那么第i-1间房间就不能够偷了,此时dp[i] = dp[i - 2] + nums[i]

对于第二种情况,如果选择不偷第i间房间,那么其值应该和前一个dp值相同,即dp[i] = dp[i - 1]

综上,可以得到以下状态转移方程:
dp[i]=max{dp[i−2]+nums[i],dp[i−1]} dp[i]=max\{dp[i-2]+nums[i],dp[i-1]\} dp[i]=max{dp[i2]+nums[i],dp[i1]}

class Solution {
    public int rob(int[] nums) {
        if (nums.length == 1) return nums[0];
        else if (nums.length == 2) return Math.max(nums[0], nums[1]);
        int[] dp = new int[nums.length];
        dp[0] = nums[0];
        dp[1] = Math.max(nums[0], nums[1]);
        for (int i = 2; i < dp.length; ++i){
            dp[i] = Math.max(dp[i - 2] + nums[i], dp[i - 1]);
        }
        return dp[nums.length - 1];
    }
}

120 三角形最小路径和

给定一个三角形 triangle ,找出自顶向下的最小路径和。

每一步只能移动到下一行中相邻的结点上。相邻的结点 在这里指的是 下标 与 上一层结点下标 相同或者等于 上一层结点下标 + 1 的两个结点。也就是说,如果正位于当前行的下标i,那么下一步可以移动到下一行的下标ii + 1

方法

考虑在位置(i,j)时,应该做的选择,存在两种方式可以到达该位置:

  • (i-1,j-1)到达
  • (i-1,j)到达

由于题目中考虑的是最小值,因此只要取两者中的较小值,同时注意边界的判断即可。状态转移方程为:
dp[i][j]=min{dp[i−1][j−1],dp[i−1][j]}+nums[i][j] dp[i][j]= min\{dp[i-1][j-1],dp[i-1][j]\}+nums[i][j] dp[i][j]=min{dp[i1][j1],dp[i1][j]}+nums[i][j]

class Solution {
    public static int MAXVALUE = 10001 * 200;
    public int minimumTotal(List<List<Integer>> triangle) {
        if (triangle.size() == 1) return triangle.get(0).get(0);
        int[][] dp = new int[triangle.size()][];
        for (int i = 0; i < triangle.size(); ++i){
            dp[i] = new int[triangle.get(i).size()];
        }
        dp[0][0] = triangle.get(0).get(0);
        for (int i = 1; i < dp.length; ++i){
            for (int j = 0; j <= i; ++j){
                int superLayer1 = (j - 1 >= 0) ? dp[i - 1][j - 1] : MAXVALUE;
                int superLayer2 = (i - 1 >= j) ? dp[i - 1][j] : MAXVALUE;
                dp[i][j] = Math.min(superLayer1, superLayer2) + triangle.get(i).get(j);
            }
        }
        int ans = MAXVALUE;
        for (int j = 0; j < dp[dp.length - 1].length; ++j)
            ans = Math.min(ans, dp[dp.length - 1][j]);
        return ans;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值