343.整数拆分
题解:
本题使用动态规划法,动态规划五部曲
1.确定dp数组以及下标含义
dp[i]:分拆数字i,可以得到最大乘积为dp[i]
2.确定递推公式
其实可以从1遍历j,然后有两种渠道得到dp[i].
一个是j * (i - j) 直接相乘。
一个是j * dp[i - j],相当于是拆分(i - j),对这个拆分不理解的话,可以回想dp数组的定义。
所以递推公式:dp[i] = max({dp[i], (i - j) * j, dp[i - j] * j});
3.dp的初始化
dp[0],dp[1]均没有意义,可以初始化为0,反正最后要的是最大乘积,dp[2]=1
4.确定遍历顺序
首先看递推公式dp[i] = max({dp[i], (i - j) * j, dp[i - j] * j}),所以要从前向后遍历。
for (int i = 3; i <= n; i++){
for(int j = 1; j < i -1; j++) {
dp[i] = max(dp[i], max((i -j) * j, dp[i - j] * j));
}
}
5.举例dp数组
打印dp数组
C语言代码如下:
int *initDP(int num) {
int* dp = (int*)malloc(sizeof(int) * (num + 1));
int i;
for(i = 0; i < num + 1; ++i) {
dp[i] = 0;
}
return dp;
}
//取三数最大值
int max(int num1, int num2, int num3) {
int tempMax = num1 > num2 ? num1 : num2;
return tempMax > num3 ? tempMax : num3;
}
int integerBreak(int n){
int *dp = initDP(n);
//初始化dp[2]为1
dp[2] = 1;
int i;
for(i = 3; i <= n; ++i) {
int j;
for(j = 1; j < i - 1; ++j) {
//取得上次循环:dp[i],原数相乘,或j*dp[]i-j] 三数中的最大值
dp[i] = max(dp[i], j * (i - j), j * dp[i - j]);
}
}
return dp[n];
}