import java.util.Arrays;
/**
* 1449. 数位成本和为目标值的最大数字
*
* 动态规划
* 1 选取更多位置的数字
* 2 二维dp数组:限制条件 花费const[i] 与 target的关系
* j为当前的总花费 j 在 0 -- target之间
* 当 j >= const[i] 时,存在两种选择
* 1 选 此时花费为dp[i][j - const[i]] + 1
* 2 不选,所有不选的选择都为 dp[i - 1][j]
*
* 如何得到选取了那些数?
* 新建 num 一个二维数组来保存
* 如果当次位置不选,该位置直接设置为 j
* 如果该位置可以放,则放置j - const[i]
*
* 困难题目 难点在如何理解保存数组
* num中,
* num[i] 代表 当前节点数值,而 num[i][j] 代表当前节点的前一个节点
* 如果该节点不能被选取,直接将该接节点的前一个节点设置值为 num[i - 1][j] 的值
* 如果当前节点已经不可选取,代表该数字已经不可选取,i--
*
* 从 9 - 1 循环,大数在前,小数在后,i--即跳到下一个数字查看是否被选择
*/
public class Solution1449 {
public String largestNumber(int[] cost, int target) {
int[][] dp = new int[10][target + 1];
for (int i = 0; i < 10; i++) {
Arrays.fill(dp[i], Integer.MIN_VALUE);
}
int[][] num = new int[10][target + 1];
dp[0][0] = 0;
for (int i = 0; i < 9; i++) {
for (int j = 0; j <= target; j++) {
if (j < cost[i]) {
dp[i + 1][j] = dp[i][j];
num[i + 1][j] = j;
} else {
if (dp[i][j] > dp[i + 1][j - cost[i]] + 1) {
dp[i + 1][j] = dp[i][j];
num[i + 1][j] = j;
} else {
dp[i + 1][j] = dp[i + 1][j - cost[i]] + 1;
num[i + 1][j] = j - cost[i];
}
}
}
}
if (dp[9][target] < 0) {
return "0";
}
StringBuffer stringBuffer = new StringBuffer();
int i = 9, j = target;
while (i > 0) {
if (j == num[i][j]) {
--i;
} else {
stringBuffer.append(i);
j = num[i][j];
}
}
return stringBuffer.toString();
}
}
LeetCode--1449. 数位成本和为目标值的最大数字
最新推荐文章于 2021-06-16 22:52:27 发布