动态规划题目汇总

70. 爬楼梯

方法:动态规划
算法

不难发现,这个问题可以被分解为一些包含最优子结构的子问题,即它的最优解可以从其子问题的最优解来有效地构建,我们可以使用动态规划来解决这一问题。

第 i 阶可以由以下两种方法得到:

在第 (i−1) 阶后向上爬一阶。

在第 (i−2) 阶后向上爬 2阶。

所以到达第 ii阶的方法总数就是到第 (i−1) 阶和第 (i−2) 阶的方法数之和。

令 dp[i]表示能到达第 i 阶的方法总数:

dp[i]=dp[i-1]+dp[i-2]

作者:LeetCode
链接:https://leetcode-cn.com/problems/climbing-stairs/solution/pa-lou-ti-by-leetcode/

int climbStairs(int n){
    if(n==1)return 1;
    int dp[n+1];
    dp[1]=1;
    dp[2]=2;
    for(int i=3;i<n+1;i++){
        dp[i]=dp[i-1]+dp[i-2];
    }
    return dp[n];
}

91. 解码方法 

 

int numDecodings(char * s){
    int dp[strlen(s)+1];
    if(s[0]=='0')return 0;
    dp[0]=1;
    if(s[1]=='0'){
        if(s[0]>'2')return 0;
        else dp[1]=1;
    }
    if(s[0]=='1'&&s[1]!='0')dp[1]=2;
    else if(s[0]=='2'&&s[1]<='6'&&s[1]>'0')dp[1]=2;
    else dp[1]=1;
    for(int i=2;i<strlen(s);i++){      
        if(s[i]=='0'){
            if(s[i-1]=='1'||s[i-1]=='2')dp[i]=dp[i-2];
            else return 0;
        }
        else {
            if(s[i-1]=='1')
                dp[i]=dp[i-1]+dp[i-2];
            else if(s[i-1]=='2'&&s[i]<='6') {
                dp[i]=dp[i-1]+dp[i-2];
            }else dp[i]=dp[i-1]; //如果dp[i]和dp[i-1]不能分解成不同的解码方法,则dp[i]=dp[i-1]
        }
        
    }
    return dp[strlen(s)-1];
}

62. 不同路径

我们令 dp[i][j] 是到达 i, j 最多路径

动态方程:dp[i][j] = dp[i-1][j] + dp[i][j-1]

注意,对于第一行 dp[0][j],或者第一列 dp[i][0],由于都是在边界,所以只能为 1

时间复杂度:O(m*n)O(m∗n)

空间复杂度:O(m * n)O(m∗n)

优化:因为我们每次只需要 dp[i-1][j],dp[i][j-1]

int uniquePaths(int m, int n){
if (0 == m || 0 == n) return 1;
int dp[m][n];
for (int i = 0; i < m; i++) {
    for (int j = 0; j < n; j++) {
        if (0 == i || 0 == j) dp[i][j] = 1;
        else {
            dp[i][j] = dp[i][j - 1] + dp[i - 1][j];
        }
    }
}
return dp[m - 1][n - 1];
}

64. 最小路径和

作者:jyd
链接:https://leetcode-cn.com/problems/minimum-path-sum/solution/zui-xiao-lu-jing-he-dong-tai-gui-hua-gui-fan-liu-c/
 

#define Min(a,b) ((a)<(b)?(a):(b));
int minPathSum(int** grid, int gridSize, int* gridColSize){
    if(grid==NULL)return 0;
    int col=* gridColSize;
    int dp[gridSize][col];
    for (int i = gridSize-1; i >= 0; i--) {
        for (int j = col- 1; j >= 0; j--) {
            if(i == gridSize - 1 && j != col - 1)
                dp[i][j] = grid[i][j] +  dp[i][j + 1];
            else if(j ==col - 1 && i != gridSize - 1)
                dp[i][j] = grid[i][j] + dp[i + 1][j];
            else if(j != col- 1 && i != gridSize - 1){
                dp[i][j] = grid[i][j] + Min(dp[i + 1][j], dp[i][j + 1]);}
            else if(i == gridSize - 1 && j ==col - 1)
                dp[i][j] = grid[i][j];
           }
       }
       return dp[0][0];

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值