0
点赞
收藏
分享

微信扫一扫

动态规划初级篇(上)

三次方 2022-03-25 阅读 79

目录

        ⌛动态规划题目特点

        👇Example1 (换硬币)

        👇Example2 (跳跃游戏)

        👇Example 3 (解密方法)

        👇Example 4(最长升序子串)

        👇Example 5(调手表)

        🚖坐标型动态规划总结

⌛动态规划题目特点

👇Example1 (换硬币)

public class Solution {
    public int coinChange(int[] coins, int amount) {
    int m = coins.length;
    if(m == 0 || amount == 0){
        return 0;
    }
    
    int[] dp = new int[amount+1];
    
    //初始化
    dp[0] = 0;
    
    for(int i=1; i<=amount; i++){
        dp[i] = Integer.MAX_VALUE;
        
        //有m个不同的硬币
        for(int j=0; j<m; j++){
            if(i >= coins[j] && dp[i-coins[j]] != Integer.MAX_VALUE){//处理边界情况
                dp[i] = Math.min(dp[i-coins[j]]+1,dp[i]);//转移方程
            }
          }
    }
        //拼不出返回-1
        if(dp[amount] == Integer.MAX_VALUE){
            return -1;
        }
        return dp[amount];
    }
}

👇Example2 (跳跃游戏)

public class Solution {
    public boolean canJump(int[] A) {
        // write your code here
        int n = A.length;
        if(n == 0 || A==null){
            return false;
        }
        boolean[] dp = new boolean[n];
        dp[0] = true;
        for(int i=1; i<n;i++){
            dp[i] = false;
            for(int j = i-1;j>=0;j--){
                if(dp[j] == true && j+A[j] >= i){
                    dp[i] = true;
                    break;
                }
            }
        }
        return dp[n-1];
    }
}

👇Example 3 (解密方法)

public class Solution {
=
    public int numDecodings(String s) {

        char[] ss = s.toCharArray();
        int n = ss.length;

        if(n == 0){
            return 0;
        }

        int[] dp = new int[n+1];
        dp[0] = 1;

        for(int i=1; i<=n; i++){
            
           dp[i] = 0;先初始化为0,可能存在不能组成字符串的情况
            
           //用一个字符作为结尾
           int t1 = ss[i-1]-'0';
           if(t1>0 && t1<=9){//若t == 0,自动选择后两位作为一个字符
               dp[i]+=dp[i-1];
           }
          
           if(i>=2){
               //取出倒数第二位
              int t2 = (ss[i-2]-'0')*10+ss[i-1]-'0';

               if(t2<=26 && t2>=10){//最后两位小于26并且大于等于10才能组成字符
                   dp[i]+=dp[i-2];
               }       
           }
        }
        return dp[n];
    }
}

👇Example 4(最长升序子串)

public class Solution {
    //计算最长升序子列
    public int MyLongstIncreasingContinuousSubsequence(int[] A){
        int n = A.length;

        if(n == 0 || A == null){
            return 0;
        }

        int[] dp = new int[n];
        //初始化
        dp[0] = 1;
        int max = 1;//记录最长字串长度

        for(int i=1; i<n;i++){
            dp[i] = 1;//若没有递增默认为1

            if(A[i]>A[i-1]){
                dp[i] = Math.max(1, dp[i-1]+1);
                max = Math.max(dp[i],max);
            }
        }
        return max;
    }
    public int longestIncreasingContinuousSubsequence(int[] A) {

        int ret1 = MyLongstIncreasingContinuousSubsequence(A);
        
        //导致字符串,计算最长降序字符串
        int left = 0;
        int right = A.length-1;
        while(left < right){
            int temp = A[left];
            A[left] = A[right];
            A[right] = temp;
            left++;
            right--;
        }

        int ret2 = MyLongstIncreasingContinuousSubsequence(A);

        int result = Math.max(ret1, ret2);

        return result;
    }
}

👇Example 5(调手表)

import java.util.Scanner;
import java.util.Arrays;

public class Solution {
    public int MinNumberOfTime {
        Scanner scan = new Scanner(System.in);
        
        int n = scan.nextInt();
        int k = scan.nextInt();

        int[] dp = new int[n];
        dp[0] = 0;初始化

        for(int i=1;i<n;i++){
          dp[i] = dp[i-1]+1;
      
          if(i-k>=0 && k>1){
            dp[i] = Math.min(dp[i-k]+1,dp[i]);
          }

          for(int j=2;j<dp[i];j++){//寻找可行的j
            
            if((j*k)%n == i){
              dp[i] = Math.min(dp[i],j);
              break;
            }

          }
        }

        排序找到最大数
        Arrays.sort(dp);

        return dp[n-1]
    }
}

🚖坐标型动态规划总结

举报

相关推荐

0 条评论