红绿塔(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));
       
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值