T70:爬楼梯
题目要求:假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
动态规划本质理解
当你达到n层时,你的上一步只能是:n-1或者n-2
也就是说:
到达 n 的方法数 =到达 n-1 的方法数+到达 n-2 的方法数
核心公式:dp[n] = dp[n-1] + dp[n-2]
就是斐波那契数列:当前数字等于前两个数相加之和
代码实现
java
if(n<=2)return n;
int a=1;
int b=2;
for(int n=3;i<n;i++){
int sum=a+b;
a=b;
b=sum;
}
return b;
总结
dp[n] = dp[n-1] + dp[n-2]
是本题的解答关键
T118:杨辉三角形
题目要求:
给定一个非负整数 numRows,生成「杨辉三角」的前 numRows 行。
在「杨辉三角」中,每个数是它左上方和右上方的数的和。
杨辉三角规律
每一行:
第一个 = 1
最后一个 = 1
中间元素 = 上一行相邻两个数之和
核心思路
一行一行构造
每一行如何构造:
- 先放一个 1
- 中间用"上一行"计算
- 最后放一个 1
代码实现
java
List<List<Integer>> res=new ArrayList<>();
for(int i=0;i<numRows;i++){
List<Integer> row=new ArrayList<>();
//每一行有i+1个元素
for(int j=0;j<=i;j++){
//第一个和最后一个都是1
if(j==0||j==i){
res.add(1);
}else{
//中间=上一行相邻两个数之和
int val=res.get(i-1).get(j-1)+res.get(i-1).get(j);
res.add(val);
}
}
}
return res;
总结
理解:
一行一行构造;每一行第一和最后是1;中间元素是上相邻两元素相加
T198:打家劫舍
题目要求:
有一排房子,每个房子有金额 nums[i]
你不能偷相邻的房子(会报警❗)
问:最多能偷多少钱?
本质
每个位置都在做"选 or 不选"的决策
核心思路
这是一个典型动态规划问题,
dp[i] 表示前 i 个房子的最大收益,
状态转移为 dp[i] = max(dp[i-1], dp[i-2] + nums[i])
代码实现
java
if(nums,length==1)return nums[0];
int a=nums[0];//dp[i-2]
int b=Math.max(nums[0];nums[1]);//dp[i-1]
for(int i=2;i<nums.length;i++){
int cur=Math.max(b,a+nums[i]);
a=b;
b=cur;
}
return b;
总结
每一轮做决策:
偷 or 不偷
dp[i] = max(dp[i-1], dp[i-2]+nums[i])
滚动变量优化