整数の動的なプログラミング部門

そこに大きな問題があると、特定の状態遷移ルールを示す特性の間に小さな問題を発見し、次いで溶液の条件を満たすように小さな問題を設計し、そして最後に、メモリ内の中間値迅速最終的な解決策を得ます

私は実際には、動的計画法の一般的なアイデアのトピックに解決することは比較的容易である、脳は考えることができない、それ以外の場合は、一般的な思考に陥る、タイトルにおける動的計画法の一般的なルールは慎重に分析した整数除算の問題を必要とします

図1に示すように、整数除算の最大積

 

 

この質問の難易嘘整数の除算では、最大の製品・ソリューションを実現(コメントがキーです)小さな問題を記録する良い方法はありませんが、実は「スプリット」で、このステップは、適切な法律、ソースコードを見つけることです

    / ** 
     *この保存に再び各整数因数分解の整数である、の関係を分解
     など* 
     * 2 = 1 + 1 
     * 1 + 1 = 3 + 1 
     * = 1 + 2 
     1 = 1 + 1 + 1 * 4 + 
     * = 1 + 2 + 1 
     * = 1 + 3 
     * = 2 + 2 
     *その後、DPにおける1 + 1 + 1および2 + 1 [3]を算出する際、J = 1横断するとき、[4] DPを算出しますオフにのみ、* 1 3算出することができる
     * J = 2 1 + 1 = 2と同じ時間を横断するが、DP [2]を算出のみ2×2に再計算される
     *ので、このチャンネルを難しい問題は、一般的な整数加算分解次の段階を見つけることです!
     * @Param N- 
     * @return 
     * / 
    プライベート INT integerBreak(INT N-){
         INT [] DP = 新しい新しい INT [N- + 1 ]; 
        DP [ 1] = 1 ;
         のためINTは I 2 =; I <= N; I ++ ){
             ためINT J = 1; J <= I - 1、J ++ ){ 
                DP [I] = Math.max(DP [I]、Math.max(J * DP [I - j]は、J *(I - J)))。
            } 
        } 
        戻りDP [n]は、
    }

整数除算の正方形によれば2、

 

一見すると、この質問は何をする再帰下降が、非常に深刻な問題を見落としすることができます!例えば、再帰の考え方によれば12 = 9 + 1 + 1、出力は4 + 1が、12 = 4 + 4 + 4は、動的プログラミングを覚えてまたは各々の中央に価値が、最小の戻り値コードされ、その結果、3であります次のように:

    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];
    }

おすすめ

転載: www.cnblogs.com/lybnumber6/p/12189489.html
おすすめ