• Leetcode 956. 最高的广告牌(DP)


    1. 最高的广告牌
      难度
      困难

    111

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

    你有一堆可以焊接在一起的钢筋 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。

    和之前做的2021ICPC上海站的题比较类似,设dp[i][j]表示考虑到前i个钢筋,状态为j时左边的最大长度。这里的状态基准为5000,如果选择将第i个钢筋分往左边则用j - rods[i]表示新的状态,分往右边则是用j + rods[i]表示新的状态。注意dp数组的初始化以及转移方程。因为对于同一个状态而言,肯定是左边尽可能大更优(状态确定了,左边尽可能大则右边同样也尽可能大),因此这样转移的正确性得以保证。特别要注意必须合法才能进行转移,因此加一个ok数组表示dp[i][j]是否合法。细节见代码:

    class Solution {
    public:
        int dp[25][10001], n, a[25];//dp[i][j]表示状态为j时左边的长度(以5000为基准)左边减
        bool ok[25][10001];
        int tallestBillboard(vector<int>& rods) {
            memset(dp, 0, sizeof(dp));
            n = rods.size();
            for(int i = 1; i <= n; i++) {
                a[i] = rods[i - 1];
                dp[i][a[i] + 5000] = 0;
                dp[i][5000 - a[i]] = a[i];
                ok[i][a[i] + 5000] = 1;
                ok[i][5000 - a[i]] = 1;
                dp[i][5000] = 0;
                ok[i][5000] = 1;
            }
            for(int i = 1; i <= n; i++) {
                for(int j = 0; j <= 10000; j++) {
                    if(ok[i - 1][j]) dp[i][j] = dp[i - 1][j], ok[i][j] = 1;
                    if(j + a[i] <= 10000 && ok[i - 1][j + a[i]]) {
                        dp[i][j] = max(dp[i][j], dp[i - 1][j + a[i]] + a[i]);
                        ok[i][j] = 1;
                    }
                    if(j - a[i] >= 0 && ok[i - 1][j - a[i]]) {
                        dp[i][j] = max(dp[i][j], dp[i - 1][j - a[i]]);//这里不能减 注意dp数组的含义!
                        ok[i][j] = 1;
                    }
                }
            }
            return dp[n][5000];
        }
    };
    
  • 相关阅读:
    [随笔][Java][修改Maven仓库库为阿里云]
    [随笔][Java][Java 类型系统]
    MongoDB终极攻略
    SQLAlchemy攻略
    linux system函数引发的错误
    QT 问题提问网站
    QT学习
    QT学习
    linux 内存
    Linux 查看内存(free)、释放内存(基本操作)
  • 原文地址:https://www.cnblogs.com/lipoicyclic/p/15981358.html
Copyright © 2020-2023  润新知