LeetCode279 完全平方数

完全平方数>>>
在这里插入图片描述> dp[i]为数字i的最少完全平方数,则其前一个状态dp[i-j*j],状态转移方程为dp[i]=Math.min(dp[i-j*j))+1


package BDyNamicProgramming;

/**
 * @Author Zhou  jian
 * @Date 2020 ${month}  2020/4/21 0021  18:03
 */
public class Problem279 {

    /**
     * 给定正整数n,找到若干个完全平方数(1,4,9,16.。。。。)
     * 组成和的完全平方数的个数最少
     * @param n
     * @return
     * dp[]
     *
     * dp[n]为凑成n的最少的数据个数,
     * 则dp[n]=1+Min(dp[n-1*1],dp[n-2*2],dp[n-3*3],dp[n-4*4],....dp[n-k*k])
     * dp[1]=1
     * dp[0]=0
     *  n必须是由给定的正整数的平方组成,
     *  所以 v[13] 可能的情况为, 1 + v[12] 或 1 + v[9] 或 1 + v[4]
     *  题目本质是01完全背包问题,和硬币找零钱是一样的
     *
     *  dp[i]:表示完全平方数和为i最小的个数
     *
     *  dp[i]为 min(dp[i],dp[i-j*j]+1)
     *
     *
     */
    public int numSquares(int n) {

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

        dp[0]=0;
        dp[1]=1;

        for(int i=2;i<=n;i++){

            //对数组进行遍历,下标为i,每次都将当前数字先更新为最大值
            //即dp[i]=i,比如i=4.最坏结果为4=1+1+1+1即为4个数字
            int MinVal = i;

            //状态转移方程:dp[i]=Math.min(dp[i],dp[i-j*j]),i表示当前数字,j*j表示平方数
            // i-j*j表示当前数前驱一个完全平方和之后dp[i-j*J]需要求的最优解 不断分解
            for(int j=1;j*j<=i;j++) MinVal=Math.min(MinVal,dp[i-j*j]);


            dp[i]=MinVal+1;

        }

        return dp[n];

    }


}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值