dp dynamic programming - primary java implementation is constantly updated -

Summary: Dynamic programming mainly consists of four steps (the original data is int[][] arr)

1. Define the array that stores the intermediate state; (You can find out the array intermediate variable that needs to be defined according to the conditions given or the problem) For example: dp[i][j] 2.
Find the relationship between the next state and the previous state, (also It can be pushed from the back to the front, which is the relationship between the previous and the next)
For example: dp[i][j]=dp[i-1][j-1]+arr[i][j]/dp[i] Relationships such as [j-1] can be pushed to the next level by acting on the straw paper yourself.
3. Find the initial values ​​of the dp[][] array
4. According to the relationship, push the arr array from front to back/from back to front until it terminates;

Question ten

	//动态规划
    public static int countVowelStrings(int n) {
    
    
        if(n==0)return 0;
        //定义一个二维数组存储数据
        int[][] nums=new int[n][5];
        for (int i = 0; i <n ; i++) {
    
    
            nums[i][0]=1;
        }
        nums[0][1]=2;
        nums[0][2]=3;
        nums[0][3]=4;
        nums[0][4]=5;
        for (int i = 1; i < n; i++) {
    
    
            for (int j = 1; j < 5; j++) {
    
    
                nums[i][j]=nums[i][j-1]+nums[i-1][j];
            }
        }
        System.out.println(123);
        return nums[n-1][4];
    }

Question 9 A subsequence is a sequence derived from an array, deleting (or not deleting) elements in the array without changing the order of the remaining elements. For example, [3,6,2,7] is a subsequence of the array [0,3,1,6,2,2,7].

public int lengthOfLIS(int[] nums) {
    
    
        int len=nums.length;
        int[][] ints=new int[len][2];
        ints[0][0]=0;
        ints[0][1]=1;
        for (int i = 1; i <len ; i++) {
    
    
            ints[i][1] = 1;
            for (int j = i-1; j >=0 ; j--) {
    
    
                if (nums[i] > nums[j]) {
    
    
                    int tem = ints[j][1] + 1;
                    ints[i][1]=Math.max(tem,ints[i][1]);
                }
            }
            ints[i][0] = Math.max(ints[i - 1][0], ints[i - 1][1]);
        }
        System.out.println(123456);
        return Math.max(ints[len-1][1],ints[len-1][0]);
    }

Question 7: Up the stairs in three steps

/**
     * 计算台阶三步问题。有个小孩正在上楼梯,楼梯有n阶台阶,小孩一次可以上1阶、2阶或3阶。
     * 实现一种方法,计算小孩有多少种上楼梯的方式。结果可能很大,你需要对结果模1000000007。
     */
    public static int waysToStep(int n) {
    
    
        if(n==0)return 0;
        if(n==1)return 1;
        if(n==2)return 2;
        long[] step=new long[n+1];
        //首先确定前几个固定元素0,1,2,3自己可以在纸上写一下上台阶方式
        //可以得到如下
        step[0]=0;
        step[1]=1;
        step[2]=2;
        step[3]=1+step[2]+step[1];
        if(n==3)return (int)step[n];
        //继续向下推导我们会发现一个有趣的推论:
        // step[i]=第一次走一步+step[i-1]+第一次走两步+step[i-2]+第一次走三步+step[i-3]
        //step[4]=step[3]+step[2]+step[1];
        //step[5]=step[4]+step[3]+step[2];
        for (int i = 4; i <= n; i++) {
    
    
            long tem=(step[i-1]+step[i-2]+step[i-3]);
            //根据题意取模运算就是取余数
            step[i]=tem>1000000007?tem%1000000007:tem;
        }
        return (int)step[n];
    }

Example 3 question: Different subsequences
Note: This is a difficult question (ps I also read the analysis of the problem solution and learned the forward analysis)
insert image description here

public static int numDistinct(String s, String t) {
    
    
        int lenj=s.length();
        int leni=t.length();
        //定义一个二维数组表示第i行第j列s与t的前几项匹配个数
        int[][] dp=new int[leni+1][lenj+1];
        //初始化第一行均为1如图中分析
        for (int i = 0; i < lenj+1; i++) {
    
    
            dp[0][i]=1;
        }
        for (int i = 1; i <= leni; i++) {
    
    
            //获取当前t的i坐标对应的char
            char tTem=t.charAt(i-1);
            for (int j = 1; j <= lenj; j++) {
    
    
                //如果当前行上s的j下标的char与t下的i下标对应的char相等则满足
                //dp[i][j]=dp[i-1][j-1]+dp[i][j-1];否则当前行对应数量与上一行无关
                //即等于此行前一个匹配的数量dp[i][j]=dp[i][j-1]
                if(tTem==s.charAt(j-1)){
    
    
                    dp[i][j]=dp[i-1][j-1]+dp[i][j-1];
                }else{
    
    
                    dp[i][j]=dp[i][j-1];
                }
            }
        }
        return dp[leni][lenj];
    }

Example 2: masseuse
insert image description here

/**
     * dp按摩师最大的工作时间
     */
    public static int massage(int[] nums) {
    
    
        //定义最终的结果以及当数组长度为0,1,2,时的情况
        int len=nums.length;
        if(len==0)return 0;
        if(len==1)return nums[0];
        if(len==2)return Math.max(nums[0],nums[1]);
        //由于不能连续工作,因此之可能是第i个前最大和为:n[i]=n[i-2]/n[i-3]+nums[i]
        //定义前i项之和arr:因此根据推倒方程式可知arr0,arr1,arr2
        int[] arr=new int[len];
        arr[0]=nums[0];
        arr[1]=nums[1];
        arr[2]=nums[2]+nums[0];
        for (int i = 3; i <len ; i++) {
    
    
            arr[i]=Math.max(arr[i-2],arr[i-3])+nums[i];
        }
        //因此最终答案一定会在len-1或len-2的位置上
        return Math.max(arr[len-1],arr[len-2]);
    }

Note: Example 1: Find the largest continuous substring.
The first is to deduce the straw paper: a little messy.
insert image description here

	/**
     * 动态规划基础题
     */
    public static int maxSubArray1(int[] nums) {
    
    
        if(nums.length==1){
    
    
            return nums[0];
        }
        int endMax=nums[0];
        //定义从前向后的连续数之和的集合
        int[] temNum=new int[nums.length];
        temNum[0]=nums[0];
        for (int i = 1; i <nums.length ; i++) {
    
    
            //找到最大的前i项之和(因为是连续子字符串所以通过推到
            // 很容易发现temNum[i]=temNum[i-1]+nums[i]或nums[i]取最大的定义第i位的最大和值
            temNum[i]=Math.max(temNum[i-1]+nums[i],nums[i]);
            //找出当前最大的在最大和数组中
            endMax=Math.max(temNum[i],endMax);
        }
        return endMax;
    }

Example 4. Odd numbers must lose and even numbers must win. . Write your own inferences to discover

/**
     * 赢得最终:小明小芳在数字N下依次取i,使得N%i==0;i可以为1,都尽力去赢
     * 小芳先选择:
     * @param N
     * @return
     */
    public static boolean divisorGame(int N) {
    
    
        //根据题意很容易知道定义一个选择结果推导数组boolean[] b
        boolean[] booleans=new boolean[N+1];
        //当n为1时和n为2时很容易分析出初始值
        booleans[1]=false;
        booleans[2]=true;
        //从第三位开始继续遍历
        for (int i = 3; i <= N; i++) {
    
    
            //即不让堆放赢,为当!booleans[i-j]&&i%j==0时有booleans[i]=true;
            //并且我们可以知道j<i/2;,大于计算无意义
            for (int j = 1; j < i/2; j++) {
    
    
                if((!booleans[i-j])&&(i%j==0)){
    
    
                    booleans[i]=true;
                    break;
                }
            }
        }
        return booleans[N];
    }

Question 6: The best profit for buying and selling stocks in one transaction

	/**
     * dp动态规划提
     * 写了三种方式
     * 第一种二维数组费空间
     * 第二种一维数组
     * 第三种定义一个变量
     */
    public static int maxProfit(int[] prices) {
    
    
        int len=prices.length;
        if(len<2)return 0;
        if(len==2)return Math.max(prices[1] - prices[0], 0);
        /*int[][] ints=new int[len][len];
        for (int i = 0; i <len ; i++) {
            ints[i][i]=0;
        }
        for (int i = 0; i < len; i++) {
            for (int j = i+1; j < len; j++) {
                ints[i][j]=Math.max(prices[j]-prices[i],ints[i][j-1]);
                if(i>0){
                    ints[i][j]=Math.max(ints[i][j],ints[i-1][j]);
                }
            }
        }
        return ints[len-2][len-1];*/
        /*int[] dp=new int[len];
        dp[0]=0;dp[1]=Math.max(prices[1] - prices[0], 0);
        for (int i = 2; i < len; i++) {
            for (int j = 0; j <i ; j++) {
                dp[i]=Math.max(dp[i],prices[i]-prices[j]);
            }
            dp[i]=Math.max(dp[i],dp[i-1]);
        }
        return dp[len-1];*/
        int minNum=Integer.MAX_VALUE;
        int maxNum=0;
        for (int i = 0; i < len; i++) {
    
    
            if(prices[i]<minNum){
    
    
                minNum=prices[i];
            }else if(prices[i]-minNum>maxNum){
    
    
                maxNum=prices[i]-minNum;
            }
        }
        return maxNum;
    }

Question 7: Each subscript of the array is used as a ladder, and the i-th ladder corresponds to a non-negative physical expenditure value cost[i] (the subscript starts from 0).

public static int minCostClimbingStairs(int[] cost) {
    
    
        int len=cost.length;
        if(len<=1)return 0;
        if(len==2)return Math.min(cost[0],cost[1]);
        //定义有一个二维数组只有两个元素的第一个表示不选当前元素,第二个表示选择当前元素
        int[][] num=new int[len][2];
        num[0][0]=0;num[0][1]=cost[0];
        num[1][0]=num[0][1];num[1][1]=cost[1];
        for (int i = 2; i < len; i++) {
    
    
            //如果当前元素未选择咋前一个元素一定选择了
            num[i][0]=num[i-1][1];
            //当前元素选择则前一个元素找出最大的和
            num[i][1]=Math.min(num[i-1][0],num[i-1][1])+cost[i];
        }
        //System.out.println("123");
        return Math.min(num[len-1][0],num[len-1][1]);
    }

Question 8 Maximum Subsequence Size

/**
     * 给定一个整数数组,找出总和最大的连续数列,并返回总和。
     */
    public static int maxSubArray123(int[] nums) {
    
    
        int len=nums.length;
        if(len==1)return nums[0];
        //定义一个返回前i个的数组的最大和---一推到直接可以观察到,,
        //所以最大数一定出自其中即为从前向后找都在一个循环里方便查询
        int max=nums[0];
        int[] data=new int[len];
        data[0]=nums[0];
        for (int i = 2; i < len; i++) {
    
    
            data[i]=Math.max(data[i-1]+nums[i],nums[i]);
            max=Math.max(data[i],max);
        }
        return max;
    }

It's so easy to get to the basics at the end haha

	/**
     * dp第八题
     */
    public static int climbStairs(int n) {
    
    
        if(n==0)return 0;
        //定一个数组表示上台阶所走的总路程
        //根据题意很容易找出地推公式。。。
        int[] nus=new int[n];
        nus[0]=1;
        if(n==1)return nus[n-1];
        nus[1]=2;
        for (int i = 2; i < n; i++) {
    
    
            nus[i]=nus[i-1]+nus[i-2];
        }
        return nus[n-1];
    }

Problem 11: Maximum Identical Substring Length Medium Difficulty

public int longestCommonSubsequence(String text1, String text2) {
    
    
        String t1;String t2;
        if(text1.length()>text2.length()){
    
    
            t1=text1;
            t2=text2;
        }else{
    
    
            t1=text2;
            t2=text1;
        }
        char[] chars2=t2.toCharArray();
        char[] chars1=t1.toCharArray();
        if(chars2.length==0)return 0;
        int[][] num=new int[chars2.length][chars1.length];
        num[0][0]=chars2[0]==chars1[0]?1:0;
        for (int i = 0; i < chars2.length; i++) {
    
    
            for (int j = 0; j < chars1.length; j++) {
    
    
                if(i==0){
    
    
                    num[0][j]=chars2[0]==chars1[j]?1:j>0?num[0][j-1]:0;
                }else if(j==0){
    
    
                    num[i][0]=chars2[i]==chars1[0]?1:num[i-1][0];
                }else {
    
    
                    num[i][j] = Math.max( num[i - 1][j] , num[i][j - 1]);
                    if (chars1[j] == chars2[i]) num[i][j]=Math.max(num[i][j],num[i-1][j-1]+1);
                }
            }
        }
        System.out.println(123);
        return num[chars2.length-1][chars1.length-1];
    }

作者:jing-tian-ming-2
链接:https://leetcode-cn.com/problems/longest-common-subsequence/solution/ao-li-gei-dong-tai-gui-hua-by-jing-tian-wbxw2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

Land Twelve Questions

public int countNumbersWithUniqueDigits(int n) {
    
    
        if(n==0)return 1;
        if(n>10)return 0;
        int[] num=new int[11];
        int tem=9*9;
        num[1]=10;
        num[2]=num[1]+tem;
        for (int i = 2; i < 10; i++) {
    
    
            tem=tem*(10-i);
            num[i+1]=num[i]+tem;
        }
        return num[n];
    }

作者:jing-tian-ming-2
链接:https://leetcode-cn.com/problems/count-numbers-with-unique-digits/solution/dpdong-tai-hua-gui-hua-by-jing-tian-ming-jw3o/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

Note: Here is my leetcode, let's work together! https://leetcode-cn.com/problems/longest-common-subsequence/solution/ao-li-gei-dong-tai-gui-hua-by-jing-tian-wbxw2/

Guess you like

Origin blog.csdn.net/weixin_43795840/article/details/114855346