紅綠塔(Java)

問題描述:

在這裏插入圖片描述

public class RedGreenTower {
    /**
     * 動態規劃解法,空間複雜度O(h*n)
     * @param n 紅色方塊的個數
     * @param m 綠色方塊的個數
     * @return
     */
    public static int solve(int n, int m) { //紅綠的總個數
        /*
         * 計算最大的h
         * 由 h(h+1)/2 <= n+m 可得 h <= sqrt(2*(n+m)), 若h*(h+1) > 2*(n+m) h--;
         */
        int h = (int) Math.sqrt(2*(n+m));
        if(h*(h+1) > 2*(n+m))
            h--;

        //記錄每層總數的數組
        int[] sumi = new int[h+1];
        int sum = 0;
        for(int k=1; k<=h; k++){
            sum += k;
            sumi[k] = sum;
        }

        /*
         * 第i層剩餘j個紅色方塊的擺法總類爲
         */

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

        //初始化
        if(m > 0){
            dp[1][n] = 1;
        }
        dp[1][n-1] = 1;

        /*
         * 如果i+1層不放置紅色方塊:if(green >= i+1) dp[i+1][j]=dp[i+1][j]+dp[i][j]
         * 如果i+1層放置紅色方塊: if(red >= i+1) dp[i+1][j-i-1] = dp[i+1][j-i-1]+dp[i][j]
         */

        for(int i=1; i<h; i++) { //層數
            for(int j=n; j>=0; j--) { //紅色剩餘的個數

                int green = m - (sumi[i]-(n-j));

                if(green >= i+1)
                    dp[i+1][j] = dp[i+1][j]+dp[i][j];
                if(j >= i+1)
                    dp[i+1][j-i-1] = dp[i+1][j-i-1]+dp[i][j];
            }
        }

        int ans = 0;
        for(int k=0; k<=n; k++) {
            ans += dp[h][k];
        }

        return ans;
    }

    

    public static void main(String[] args) {
        System.out.println(solve(2,5));
       
    }

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章