版权声明:本文为博主原创文章,欢迎大家转载,但是要注明我的文章地址。 https://blog.csdn.net/program_developer/article/details/84145827
279. Perfect Squares
Description:
Given a positive integer n, find the least number of perfect square numbers (for example,
1, 4, 9, 16, ...
) which sum to n.
Example 1:
Input: n = 12 Output: 3 Explanation: 12 = 4 + 4 + 4.
Example 2:
Input: n = 13 Output: 2 Explanation: 13 = 4 + 9.
题目分析:
这是一道动态规划题目,要解决动态规划题目需要掌握三个信息:
- 最优子结构(最难的是发现最优子结构)
- 边界条件
- 根据最优子结构写出状态转移方程
重叠子问题:
我们用数组dp[i]表示第i个数字的完美平方数。我们来寻找重叠子问题:
我们要找到13的完美平方数,就把13拆成两个数的和,在分别找到这两个数的完美平方数,这就是这道题的重叠子问题。但是有一点我们不能忽略,如果这个13刚好是一个数的平方,那么它的完美平方数就是1。
最优子结构分析:
13的完美平方数 = Min( dp[i]+dp[13-i] , dp[13]) ; i = 1到 13/2。
状态转移方程:
根据上面分析出来的最优子结构,我们可以写出来这道题的状态转移方程:
i 的完全平方数是从和为 i 的两个完全平方数 dp[j] 和 dp[i-j]之和 与 dp[i ]中取最小。
【类似题目】
已经AC的代码:
import java.util.Arrays;
public class Numsquares_279 {
public static void main(String[] args) {
// TODO Auto-generated method stub
for(int i=1; i<=20; i++)
System.out.println(numSquares(i));
}
public static int numSquares(int n) {
int[] dp = new int[n+1];
Arrays.fill(dp, Integer.MAX_VALUE);
dp[1] = 1;
for(int i=1; i<=n; i++) {
int sqr = (int)Math.sqrt(i);
//如果i本身是个平方数,就将dynamicProgramming[i]置为1
if(sqr * sqr == i)
dp[i] = 1;
else {
//从1开始遍历所有和为i的最优解dp[i],使得dp[i]取值最小
for(int j=1; j<=i/2; j++)
dp[i] = Math.min(dp[j]+dp[i-j], dp[i]);
}
}
return dp[n];
}
}
Reference: