我敢保证这道题是在今早蹲厕所的时候突然冒出的解法。第一次接触DP题,我好伟大啊啊啊~
题目:一个N阶的梯子,一次能够走1步或者2步,问有多少种走法。
解法:原始DP问题。
思路:
1、if N == 1 , then ans = 1;
2、if N == 2 , then ans = 2;
3、if 我们现在在N-1阶处,现在已经有f(N-1)种走法,那么到N阶处,则还是f(N - 1)种走法(再走一步到终点)。
4、if 我们现在在N-2阶处,现在已经有f(N-2)种走法,那么到N阶处,则还是f(N -
2)种走法(一下子走两步到终点;如果走一步到N-1阶处,这种走法已经包含在f(N-1)中了,因此从N-2阶处到N阶处只有f(N-2)种走法)
综上所述:f(N) = f(N-1) +
f(N-2)。
代码:
1、标准回溯解法:超时,一般回溯代码会有过多的循环嵌套,中间结果经过多次重复计算造成超时。
1 int climbStairs(int n) {
2 if (n == 1) return 1;
3 if (n == 2) return 2;
4 return climbStairs(n-1) + climbStairs(n-2);
5 }
2、标准DP:(AC)
1 public int climbStairs(int n) {
2 if(n == 1) return 1;
3 else if(n == 2) return 2;
4
5 int[] record = new int[n + 1];
6 record[1] = 1;
7 record[2] = 2;
8 for(int i = 3 ; i <= n ; i++){
9 record[i] = record[i-1] + record[i-2];
10 }
11 return record[n];
12 }
3、DP优化,减少变量,AC。每次保存相邻的三个变量即可:这里我还用了一个flag变量做标记进行迭代赋值,网络上的代码省去了flag,先留着,后面熟悉DP了再看看。
1 public int climbStairs(int n) {
2 if(n == 1) return 1;
3 else if(n == 2) return 2;
4
5 int first = 1 , second = 2 , three = 0;
6 boolean flag = true;
7 for(int i = 3 ; i <= n ; i++){
8 three = second + first;
9 if(flag){
10 first = three;
11 flag = false;
12 }else{
13 second = three;
14 flag = true;
15 }
16 }
17 return three;
18 }
时间: 2024-12-03 05:30:39