LeetCode 956. Tallest Billboard

原题链接:https://leetcode.com/problems/tallest-billboard/

题目描述

    你正在安装一个广告牌,并希望它高度最大。这块广告牌将有两个钢制支架,两边各一个。每个钢支架的高度必须相等。

你有一堆可以焊接在一起的钢筋。举个例子,如果钢筋的长度为 1、2 和 3,则可以将它们焊接在一起形成长度为 6 的支架。

返回广告牌的最大可能安装高度。如果没法安装广告牌,请返回 0。
样例
输入:[1,2,3,6]
输出:6
解释:我们有两个不相交的子集 {1,2,3} 和 {6},它们具有相同的和 sum = 6。


输入:[1,2,3,4,5,6]
输出:10
解释:我们有两个不相交的子集 {2,3,5} 和 {4,6},它们具有相同的和 sum = 10。


输入:[1,2]
输出:0
解释:没法安装广告牌,所以返回 0。


注意
0 <= rods.length <= 20
1 <= rods[i] <= 1000
钢筋的最大长度最多为 5000

算法

(动态规划) O(n⋅∑rods[i])O(n⋅∑rods[i])
1、状态 f(i,j)f(i,j) 表示考虑了前 ii 个钢筋,搭建的两个钢制支架差距为 jj 时,较低的支架的最大高度是多少。
2、初始化 f(i,j)=−∞f(i,j)=−∞,f(0,0)=0f(0,0)=0。
3、转移时,如果不用第 ii 个钢筋,则 f(i,j)=max(f(i,j),f(i−1,j))f(i,j)=max(f(i,j),f(i−1,j));如果使用了第 ii 个钢筋,设它的高度为 x,并将它放到了较高的支架上,则差距会扩大 x,即 f(i,j+x)=max(f(i,j+x),f(i−1,j))f(i,j+x)=max(f(i,j+x),f(i−1,j));若放到了较低的支架上,并且 x 小于等于差距 jj,则 f(i,j−x)=max(f(i,j−x),f(i−1,j)+x)f(i,j−x)=max(f(i,j−x),f(i−1,j)+x),否则 f(i,x−j)=max(f(i,x−j),f(i−1,j)+j)f(i,x−j)=max(f(i,x−j),f(i−1,j)+j)。
4、最终答案为 f(n,0)f(n,0)。


时间复杂度
总共 n⋅∑rods[i]n⋅∑rods[i] 个状态,每个状态有四种转移,故总时间复杂度为 O(n⋅∑rods[i])O(n⋅∑rods[i])。

C++代码

class Solution {
public:
    int tallestBillboard(vector<int>& rods) {
        int n = rods.size(), sum = 0;
        vector<vector<int>> f(n + 1, vector<int>(5010, -5010));

        f[0][0] = 0;
        for (int i = 1; i <= n; i++) {
            sum += rods[i - 1];
            for (int j = 0; j <= sum; j++) {
                f[i][j] = max(f[i][j], f[i - 1][j]);
                int x = rods[i - 1];
                if (j + x <= sum)
                    f[i][j + x] = max(f[i][j + x], f[i - 1][j]);
                if (x <= j)
                    f[i][j - x] = max(f[i][j - x], f[i - 1][j] + x);
                else
                    f[i][x - j] = max(f[i][x - j], f[i - 1][j] + j);
            }
        }

        return f[n][0];
    }
};
发布了31 篇原创文章 · 获赞 38 · 访问量 5032

猜你喜欢

转载自blog.csdn.net/qq_41685265/article/details/104208274
今日推荐