Dynamic Programming division of integers

There are big problems and find small problems between the characteristics listed certain state transition rules, and then design a small problem to meet the conditions of the solution, and finally with intermediate values in memory quickly obtain a final solution

I need integer division issue the general rules of dynamic programming in the title carefully analyzed, otherwise it will fall into the general thinking, brains can not think, in fact, to the topic of the general idea of ​​dynamic programming is relatively easy to solve

1, the maximum product of the integer division

 

 

This question difficulty lies in integer division and achieve maximum product solution is no good way to record a small problem, but in fact "split" This step is to find an appropriate law, the source code (the comment is the key)

    / ** 
     * are each the integer factorization integers again to this Save exploded relationship, 
     * such as 
     * 2 = 1 + 1 
     * 1 + 1 = 3 + 1 
     * = 1 + 2 
     * 4 + 1 = 1 + 1 + 1 
     * = 1 + 2 + 1 
     * = 1 + 3 
     * = 2 + 2 
     * then when calculating dp [4], when traversed j = 1 when 1 + 1 + 1 and 2 + 1 in the DP [3] calculated off, only then can calculate a 3 * 1 
     * j = 2 to traverse the same time 1 + 1 = 2 are DP [2] are calculated only recalculated to a 2 * 2 
     * so that this channel difficult question is to find common integer addition decomposition when the next phase! 
     * @Param n- 
     * @return 
     * / 
    Private  int integerBreak ( int n-) {
         int [] DP = new new  int [n-+. 1 ]; 
        DP [ . 1] =. 1 ;
         for (int i = 2; i <= n; i++) {
            for (int j = 1; j <= i - 1; j++) {
                dp[i] = Math.max(dp[i], Math.max(j * dp[i - j], j * (i - j)));
            }
        }
        return dp[n];
    }

2, according to the square of an integer division

 

At first glance, this question can descending recursion to do, but overlooked a very serious problem! For example, according to the idea of ​​recursion 12 = 9 + 1 + 1 + 1, then the output is 4, but 12 = 4 + 4 + 4 is 3, so that dynamic programming to remember or to the middle of each is worth a minimum return value, the code as follows:

    private int numSquares(int n){
        int[] dp = new int[n+1];
        List<Integer> list = generateSquareList(n);
        dp[0] = 0;
        /**
         * 遍历存储每一个数的最小组合
         */
        for(int i = 1 ; i <= n ; i++){
            int min = Integer.MAX_VALUE;
//            for (int j = list.size() - 1 ; j >= 0 ; j--){
//                int now = list.get(j);
//                if(now > i)
//                    continue;
//                min = Math.min(min, dp[i - now] + 1);
//            }
            for(int j : list){
                if(j > i)
                    break;
                min = Math.min(min, dp[i - j] + 1);
            }
            dp[i] = min;
        }
        return dp[n];
    }

    private List<Integer> generateSquareList(int n) {
        List<Integer> squareList = new ArrayList<>();
        int square = 1;
        int i = 1;
        while (square <= n){
            squareList.add(square);
            square = (i+1)*(i+1);
            i += 1;
        }
        return squareList;
    }

    private int numSquaresMyWrong(int n){
        /**
         * 我这种算法没有记忆功能
         * 类似于贪心思想,但是没法判断贪心的结果是正确的
         * 要能记忆下来以前的那种情况是最优的
         */
        if(n <= 0) return 0;
        return numSquaresMyWrong(n - ((int) Math.sqrt(n) * (int) Math.sqrt(n))) + 1;
    }

3、分割整数构成字符串

 

 这道题思路来说相对比较简单,类似于裴波那契数列中的爬楼梯问题,总是1.2,但是呢他是有条件的,即不可以为0也不能大于26,而且注意的是不只是0不可以,00也不可以!

    int[] dp;
    private int numDecodings(String s){
        if(s.length() == 0) return 0;
        if(s.charAt(0) == '0') return 0;
        if(s.length() == 1) {
            if (s.charAt(0) == '0') return 0;
            else return 1;
        }
        dp = new int[s.length()+1];
        Arrays.fill(dp, -1);
        dp[0] = 1;
        return helper(s, s.length());
    }

    private int helper(String s, int n){
        if(dp[n] != -1) return dp[n];
        int sum = 0;
        for(int i = 1 ; i <= 2 ; i++){
            if(i == 1){
                if(s.charAt(n-1) != '0'){
                    sum = sum + helper(s, n - 1);
                }
            }else {

                if(n < 2) break;
                if(s.charAt(n-2) == '0') break;//也不能是00
                if(Integer.parseInt(s.substring(n-2, n)) > 26) break;
                else sum = sum + helper(s, n-2);
            }
        }
        dp[n] = sum;
        return dp[n];
    }

Guess you like

Origin www.cnblogs.com/lybnumber6/p/12189489.html