LeetCode #956 Tallest Billboard 最高的廣告牌 956 Tallest Billboard 最高的廣告牌

956 Tallest Billboard 最高的廣告牌

Description:
You are installing a billboard and want it to have the largest height. The billboard will have two steel supports, one on each side. Each steel support must be an equal height.

You are given a collection of rods that can be welded together. For example, if you have rods of lengths 1, 2, and 3, you can weld them together to make a support of length 6.

Return the largest possible height of your billboard installation. If you cannot support the billboard, return 0.

Example:

Example 1:

Input: rods = [1,2,3,6]
Output: 6
Explanation: We have two disjoint subsets {1,2,3} and {6}, which have the same sum = 6.

Example 2:

Input: rods = [1,2,3,4,5,6]
Output: 10
Explanation: We have two disjoint subsets {2,3,5} and {4,6}, which have the same sum = 10.

Example 3:

Input: rods = [1,2]
Output: 0
Explanation: The billboard cannot be supported, so we return 0.

Constraints:

1 <= rods.length <= 20
1 <= rods[i] <= 1000
sum(rods[i]) <= 5000

題目描述:
你正在安裝一個廣告牌,並希望它高度最大。這塊廣告牌將有兩個鋼製支架,兩邊各一個。每個鋼支架的高度必須相等。

你有一堆可以焊接在一起的鋼筋 rods。舉個例子,如果鋼筋的長度爲 1、2 和 3,則可以將它們焊接在一起形成長度爲 6 的支架。

返回廣告牌的最大可能安裝高度。如果沒法安裝廣告牌,請返回 0。

示例 :

示例 1:

輸入:[1,2,3,6]
輸出:6
解釋:我們有兩個不相交的子集 {1,2,3} 和 {6},它們具有相同的和 sum = 6。

示例 2:

輸入:[1,2,3,4,5,6]
輸出:10
解釋:我們有兩個不相交的子集 {2,3,5} 和 {4,6},它們具有相同的和 sum = 10。

示例 3:

輸入:[1,2]
輸出:0
解釋:沒法安裝廣告牌,所以返回 0。

提示:

0 <= rods.length <= 20
1 <= rods[i] <= 1000
鋼筋的長度總和最多爲 5000

思路:

動態規劃
題目可以轉化爲每個數字乘以 -1, 0, 1 之後和爲 0 的子數組中所有正數最大的和
比如 [1, 2, 3, 6] 可以轉換爲 [1, 2, 3, -6] 數組之和爲 0, 正數部分爲 1 + 2 + 3 = 6
用哈希表來存儲每一步的結果, dp[i] 記錄總和爲 i 時正數的最大和
比如 [1, 2, 3], 初始化 dp[0] = 0
先計算 1, dp[0] = 0, dp[1] = 1, dp[-1] = 0
然後計算 2, 對 dp 中每一個鍵進行遍歷, 比如 0 + 2 * -1/0/1 -> -2/0/2, 最後 dp[0] = 0, dp[1] = 2, dp[-1] = 1, dp[2] = 2, dp[-2] = 0, dp[3] = 3, dp[-3] = 0, 每個鍵都取最大值, 注意這裏最大值應該取最新值, 鍵應該取之前的鍵
最後返回 dp[0]
時間複雜度爲 O(sn), 空間複雜度爲 O(sn), n 爲 rods 數組的長度, s 爲 數組中元素和

代碼:
C++:

class Solution 
{
public:
    int tallestBillboard(vector<int>& rods) 
    {
        unordered_map<int, int> m;
        m[0] = 0;
        for (const auto& x : rods)
        {
            unordered_map<int, int> cur(m);
            for (const auto& [k, v] : cur)
            {
                m[k + x] = max(m[k + x], cur[k] + x);
                m[k - x] = max(m[k - x], cur[k]);
            }
        }
        return m[0];
    }
};

Java:

class Solution {
    public int tallestBillboard(int[] rods) {
        int d = 0, n = rods.length, dp[][] = new int[n + 1][5001];
        for (int i = 0; i <= n; i++) Arrays.fill(dp[i], -5001);
        dp[0][0] = 0;
        for(int i = 0; i < n; ++i) {
            d += rods[i];
            for (int j = 0; j <= d; ++j) {
                dp[i + 1][j] = Math.max(dp[i + 1][j], dp[i][j]);
                if (j + rods[i] <= d) dp[i + 1][j + rods[i]] = Math.max(dp[i + 1][j + rods[i]], dp[i][j]);
                dp[i + 1][Math.abs(j - rods[i])] = Math.max(dp[i + 1][Math.abs(j - rods[i])], dp[i][j] + Math.min(rods[i], j));
            }
        }
        return dp[n][0];
    }
}

Python:

class Solution:
    def tallestBillboard(self, rods: List[int]) -> int:
        dp = { 0: 0 }
        for x in rods:
            for d, y in list(dp.items()):
                dp[d + x] = max(dp.get(x + d, 0), y)
                dp[abs(d - x)] = max(dp.get(abs(d - x), 0), y + min(d, x))
        return dp[0]
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章