题目:
给你一个整数 n
,返回 和为 n
的完全平方数的最少数量 。
完全平方数 是一个整数,其值等于另一个整数的平方;换句话说,其值等于一个整数自乘的积。例如,1
、4
、9
和 16
都是完全平方数,而 3
和 11
不是。
思路:本题 属于完全背包问题,完全平方数属于物品,可重复取用,整数mn属于背包。
动态规划五部曲:
1.确定dp数组及含义
dp数组为一维数组,dp[i]代表和为i的完全平方数的最小数量。
2.确定递推公式
dp[i]=min(dp[i],dp[i-j*j]+1)
3.初始化dp数组
由于递推公式中我们取min,因此初始化数组应该为整数最大值,这样后面的递推中才能被被覆盖。dp[0]=0,表示和为0的完全平方数的最小数量为0
4.确定遍历顺序
本题求得是组合数,因此先遍历物品再遍历背包容量
5.举例推导dp数组
n=5,初始化dp=[0,max,max,max,max,max]
dp[0]=0
dp[1]=min(dp[1],dp[1-1*1]+1)=1
dp[2]=min(dp[2],dp[2-1*1]+1)=2
dp[3]=min(dp[3],dp[3-1*1]+1)=3
dp[4]=min(dp[4],dp[4-1*1]+1,dp[4-2*2]+1)=1
dp[5]=min(dp[5],dp[5-1*1]+1,dp[5-2*2]+1)=2
代码:
public int numSquares(int n) {
int[] dp=new int[n+1];
for(int i=0;i<=n;i++){
dp[i]=Integer.MAX_VALUE;
}
dp[0]=0;
for(int i=0;i<=n;i++){//遍历背包
for(int j=1;j*j<=i;j++){//遍历物品
dp[i]=Math.min(dp[i],dp[i-j*j]+1);
}
}
return dp[n];
}