动态规划—— 礼物的最大价值(转载)

1.动态规划的解题思路

  1. 将原问题分解为子问题
    把原问题分解为若干个子问题,子问题和原问题形式相同 或类似,只不过规模变小了
    子问题的解一旦求出就会被保存,所以每个子问题只需求 解一次
  2. 确定状态
    在用动态规划解题时,我们往往将和子问题相 关的各个变量的一组取值,称之为一个“状态”。一个“状态”对应于一个或多个子问题, 所谓某个“状态”下的“值”,就是这个“状 态”所对应的子问题的解。
  3. 确定一些初始状态(边界状态)的值
  4. 确定状态转移方程

2解题思路

2.1题干

在一个 m*n 的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于 0)。你可以从棋盘的左上角开始拿格子里的礼物,并每次向右或者向下移动一格、直到到达棋盘的右下角。给定一个棋盘及其上面的礼物的价值,请计算你最多能拿到多少价值的礼物?

class Solution {
    
    
    public int maxValue(int[][] grid) {
    
    
        int m = grid.length, n = grid[0].length;
        for(int i = 0;i <m ;i++){
    
    
            for(int j = 0;j<n;j++){
    
    
                if(i == 0 && j == 0) continue;
                if(i == 0 ) grid[i][j] += grid[i][j-1];
                else if(j == 0) grid[i][j] += grid[i-1][j];
                else grid[i][j] += Math.max(grid[i][j-1],grid[i-1][j]);
            }
            
        }
        return grid[m-1][n-1];

    }
}

根据题目说明,易得某单元格只可能从上边单元格或左边单元格到达。

设 f(i, j)为从棋盘左上角走至单元格 (i ,j) 的礼物最大累计价值,易得到以下递推关系:f(i,j)f(i,j) 等于 f(i,j-1) 和 f(i-1,j) 中的较大值加上当前单元格礼物价值 grid(i,j)

f(i,j) = max[f(i,j-1), f(i-1,j)] + grid(i,j)
f(i,j)=max[f(i,j−1),f(i−1,j)]+grid(i,j)

因此,可用动态规划解决此问题,以上公式便为转移方程。

状态定义: 设动态规划矩阵 dp,dp(i,j) 代表从棋盘的左上角开始,到达单元格 (i,j)(i,j) 时能拿到礼物的最大累计价值。
在这里插入图片描述

3.动态规划的其他题目

3.1把数字翻译成字符串

给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,1 翻译成 “b”,……,11 翻译成 “l”,……,25 翻译成 “z”。一个数字可能有多个翻译。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。

class Solution {
    
    
    public int translateNum(int num) {
    
    
        char[] ch =String.valueOf(num).toCharArray();
        int len = ch.length;
        int[] dp = new int[len+1];
        dp[0] = 1;
        dp[1] = 1;
        for(int i =2;i<= len;i++){
    
    
            int n = (ch[i-2] -'0')*10 +(ch[i-1]-'0');
            if(n>= 10 && n<=25){
    
    
                dp[i] = dp[i-1] +dp[i-2];
            }else{
    
    
                dp[i] =dp[i-1];
            }
        }
        return dp[len];
    }
}

3.2丑数

我们把只包含质因子 2、3 和 5 的数称作丑数(Ugly Number)。求按从小到大的顺序的第 n 个丑数。

class Solution {
    
    
    public int nthUglyNumber(int n) {
    
    
        int a =0,b=0,c =0;
        int[] dp  = new int[n];
        dp[0] = 1;
        for(int i = 1;i<n ;i++){
    
    
            int n2 = dp[a]* 2,n3 =dp[b]*3,n5=dp[c]*5;
            dp[i] =Math.min(Math.min(n2,n3),n5);
            if(dp[i] == n2) a++;
            if(dp[i] == n3) b++;
            if(dp[i] == n5) c++;
        }
        return dp[n-1];
    }
}

作者:jyd
链接:h
ttps://leetcode-cn.com/problems/li-wu-de-zui-da-jie-zhi-lcof/solution/mian-shi-ti-47-li-wu-de-zui-da-jie-zhi-dong-tai-gu/
来源:力扣(LeetCode)

猜你喜欢

转载自blog.csdn.net/qq_21561833/article/details/122776327
今日推荐