Form Largest Integer With Digits That Add up to Target

Given an array of integers cost and an integer target. Return the maximum integer you can paint under the following rules:

  • The cost of painting a digit (i+1) is given by cost[i] (0 indexed).
  • The total cost used must be equal to target.
  • Integer does not have digits 0.

Since the answer may be too large, return it as string.

If there is no way to paint any integer given the condition, return "0".

Example 1:

Input: cost = [4,3,2,5,6,7,2,5,5], target = 9
Output: "7772"
Explanation:  The cost to paint the digit '7' is 2, and the digit '2' is 3. Then cost("7772") = 2*3+ 3*1 = 9. You could also paint "977", but "7772" is the largest number.
Digit    cost
  1  ->   4
  2  ->   3
  3  ->   2
  4  ->   5
  5  ->   6
  6  ->   7
  7  ->   2
  8  ->   5
  9  ->   5

思路:这题暴力解,就是backtracking,但是这题这样想:我选择一个数之后,target减少,那么给定target找最大的数,又是一个子问题,那么给定target,就有最优解,那么这可以用dp来cache住最优解,那么就是我选择了一个数d + dfs(subproblem),我每次从9往0走,greedy的走,这样只要result的string的长度在增加,那么就是最优的,因为前面都是最优的解,我cache住了,那么从后往前走,得到的最长的string,就是最优的解;huahua有个思维导图,很清晰,贴过来,就是怎么表示subproblem;

class Solution {
    public String largestNumber(int[] cost, int target) {
        String[] dp = new String[target + 1];
        return dfs(cost, target, dp);
    }
    
    private String dfs(int[] cost, int target, String[] dp) {
        if(target < 0) {
            return "0";
        }
        if(target == 0) {
            return "";
        }
        if(dp[target] != null) {
            return dp[target];
        }
        String res = "0";
        for(int d = 9; d >= 1; d--) {
            String cur = dfs(cost, target - cost[d - 1], dp);
            if(cur.equals("0")) {
                continue;
            }
            cur = d + cur;
            if(res.equals("0") || cur.length() > res.length()) {
                res = cur;
            }
        }
        dp[target] = res;
        return dp[target];
    }
}

 思路2:这题可以buttom up写;计算顺序就是:t从1到target,然后d从1到9,一个个试探,生成最优解;

class Solution {
    public String largestNumber(int[] cost, int target) {
        String[] dp = new String[target + 1];
        Arrays.fill(dp, "0");
        dp[0] = "";
        for(int t = 1; t <= target; t++) {
            for(int d = 1; d <= 9; d++) {
                int s = t - cost[d - 1];
                if(s < 0 || dp[s].equals("0") || dp[s].length() + 1 < dp[t].length()) {
                    continue;
                }
                dp[t] = d + dp[s];
            }
        }
        return dp[target];
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值