文章目录
Leetcode509
1.问题描述
2.解决方案
解法一:递归使用dp记忆化搜索进行优化
就是递归要进行很多次重复计算,通过dp数组来将计算过的值记录下来,从而省去重复计算
//递归加dp记忆化搜索优化
class Solution {
public:
int dp[31];
void init(){
memset(dp,-1,31*sizeof(int));
dp[0]=0;
dp[1]=1;
}
int f(int n){
if(dp[n]!=-1) return dp[n];
else{
dp[n]=fib(n-1)+fib(n-2);
return dp[n];
}
}
int fib(int n) {
init();
return f(n);
}
};
解法二:迭代dp
//迭代dp
class Solution1 {
public:
int fib(int n) {
int dp[31];
dp[0]=0;
dp[1]=1;
if(n<2) return dp[n];
for(int i=2;i<=n;i++){
dp[i]=dp[i-1]+dp[i-2];
}
return dp[n];
}
};
解法三:矩阵快速幂(还没看)
class Solution {
public:
int fib(int n) {
if (n < 2) {
return n;
}
vector<vector<int>> q{{1, 1}, {1, 0}};
vector<vector<int>> res = matrix_pow(q, n - 1);
return res[0][0];
}
vector<vector<int>> matrix_pow(vector<vector<int>>& a, int n) {
vector<vector<int>> ret{{1, 0}, {0, 1}};
while (n > 0) {
if (n & 1) {
ret = matrix_multiply(ret, a);
}
n >>= 1;
a = matrix_multiply(a, a);
}
return ret;
}
vector<vector<int>> matrix_multiply(vector<vector<int>>& a, vector<vector<int>>& b) {
vector<vector<int>> c{{0, 0}, {0, 0}};
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
c[i][j] = a[i][0] * b[0][j] + a[i][1] * b[1][j];
}
}
return c;
}
};
解法四:通项公式(还没看)
class Solution {
public:
int fib(int n) {
double sqrt5 = sqrt(5);
double fibN = pow((1 + sqrt5) / 2, n) - pow((1 - sqrt5) / 2, n);
return round(fibN / sqrt5);
}
};
Leetcode70
1.问题描述
2.解决方案
解法一:普通dp思想
就直接dp就好
class Solution {
public:
int climbStairs(int n) {
if(n<3) return n;
int dp[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];
}
};
解法二:完全背包dp思想
代码sxl上面有具体介绍,就是将这个简单问题一般化,如果有1…m台阶梯作为物品然后抽象成完全背包问题,对于每一种台阶也就是1还是2还是m都有选几个和不选两种情况所以符合完全背包问题,又由于求的是排列数而不是组合数,所以要先遍历背包后遍历物品
class Solution1 {
public:
int climbStairs(int n) {
vector<int> dp(n+1,0);
dp[0]=1;
for(int i=0;i<=n;i++){ //遍历背包
for(int j=1;j<=2;j++){ //遍历物品
if(i>=j) dp[i]=dp[i]+dp[i-j];
}
}
return dp[n];
}
};