【完全揹包】A002_數位成本和爲目標值的最大數字(字符串 dp)

一、Problem

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”.

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 "997", 
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

二、Solution

方法一:字符串 dp

  • 定義狀態
    • dp[j]dp[j] 表示用代價 jj 可組成的最大數字
  • 思考初始化:
    • dp[0] = "",dp[1...tar] = INF 表示初始狀態下,尚且不能用大於 0 的代價數值組成數字。
  • 思考狀態轉移方程
    • dp[j] = max((i+1) + dp[j-cost[i]], dp[j]) 表示如果狀態 j-cost[i] 可達,那麼代價 jj 將有兩種合成數字的方式,分別是:
      • dp[j]
      • (i+1) + dp[j-cost[i]]
  • 思考輸出dp[tar]dp[tar] 題目要求…
class Solution {
	boolean cmp(String a, String b) {
		if (a.length() != b.length()) return a.length() > b.length();
		for (int i = 0; i < a.length(); i++) {
			if (a.charAt(i) != b.charAt(i))
				return a.charAt(i) > b.charAt(i);
		}
		return false;
	}
	public String largestNumber(int[] cost, int tar) {
		String INF = "-", dp[] = new String[tar+5]; dp[0] = "";
		for (int i = 1; i <= tar; i++)
			dp[i] = INF;
		
		for (int i = 0; i < cost.length; i++)
		for (int j = cost[i]; j <= tar; j++) {
			if (INF.equals(dp[j-cost[i]]))
				continue;
			String s = (i + 1) + "" + dp[j-cost[i]];
			if (cmp(s, dp[j])) dp[j] = s;
		}
		return INF.equals(dp[tar]) ? "0" : dp[tar];
	}
}

複雜度分析

  • 時間複雜度:O(tar×N)O(tar × N)
  • 空間複雜度:O(tar)O(tar)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章