1 爬楼梯
题目:
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
解题思路:
这是一道最简单的动态规划的题目,我们可以这么假设,当n>2时,我们可以到达楼顶的方法数为f(n)=f(n-1)+f(n-2)。
代码实现
class Solution {
public int climbStairs(int n) {
if (n <= 2) {
return n;
}
int[] dp = new int[n + 1];
dp[1] = 1;
dp[2] = 2;
for (int i = 3; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 2];
}
return dp[n];
}
}
2 使用最小花费爬楼梯
题目
给你一个整数数组 cost ,其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择向上爬一个或者两个台阶。
你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。
请你计算并返回达到楼梯顶部的最低花费。
解题思路
假设我们设定f(n)表示到达第n层所需的最小花费,从题目中我们可以推算出;由于可以从下标为 0 或下标为 1 的台阶开始爬楼梯,所以我们可以推断出f(0)=0;f(1)=0;
代码实现
class Solution {
public int minCostClimbingStairs(int[] cost) {
// 爬到顶层的最下花费
int[] dp = new int[cost.length + 1];
dp[0] = 0;
dp[1] = 0;
for (int i = 2; i < cost.length + 1; i++) {
dp[i] = Math.min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);
}
return dp[cost.length];
}
}
3 整数拆分
题目
给定一个正整数 n ,将其拆分为 k 个正整数的和( k >= 2 ),并使这些整数的乘积最大化。返回你可以获得的最大乘积。
解题思路
假设我们设定f(n)表示为将正整数i拆分成至少两个正整数的和之后,这些正整数的最大乘积。
所以当i>=2时,假设对正整数i拆分出的第一个正整数是j(1<=j<i),则有以下两种方案:
-
将i拆分成j和i−j的和,且i−j不再拆分成多个正整数,此时的乘积是 j×(i−j);
-
将i拆分成j和i−j的和,且i−j继续拆分成多个正整数,此时的乘积是 j×dp[i−j]。
代码实现
class Solution {
public int integerBreak(int n) {
// 当n=i时,可以获得的最大乘积
int[] dp = new int[n + 1];
for (int i = 2; i <= n; i++) {
int curMax = 0;
for (int j = 1; j < i; j++) {
curMax = Math.max(curMax, Math.max(j * (i - j), j * dp[i - j]));
}
dp[i] = curMax;
}
return dp[n];
}
}