LeetCode周赛#114 Q4 Tallest Billboard(动态规划)

题目来源:https://leetcode.com/contest/weekly-contest-114/problems/tallest-billboard/

问题描述

 956. Tallest Billboard

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 have a collection of rods which 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 1:

Input: [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: [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: [1,2]
Output: 0
Explanation: The billboard cannot be supported, so we return 0.

 

Note:

  1. 0 <= rods.length <= 20
  2. 1 <= rods[i] <= 1000
  3. The sum of rods is at most 5000.

------------------------------------------------------------

题意

给定一个序列,求最大的M,使得存在两个不相交的子列,子列和都是M.

------------------------------------------------------------

思路

动态规划。自己实在是想不出来,思路参考了酒井算协比赛部题解

记两个子列中子列和大者为big, 小者为small.

用dp[i][j]表示考虑到前i个rods的情况下,big比small子列和大j时big的最大子列和。

状态转移条件有4种:

1. 第i个rod没有使用;

2. 第i个rod给了big;

3. 第i个rod给了small,且给了small之后没有使得big和small地位反转;

4. 第i个rod给了small,且给了small之后使得big和small地位反转。

答案就是dp[n][0].

有两个注意点:

1. dp[i][0] (i>0)是可能的,因此要赋值为一个绝对值很大的负数而不能赋值为0;

2. dp[0][0] = 0.

------------------------------------------------------------

代码

class Solution {
public:
    int dp[25][5005];   // dp[i][j] = when i rods are used and "big" is longer than "small" with length j, the maximum length of "big"
    int tallestBillboard(vector<int>& rods) {
        int i, j, cur, n = rods.size();
        memset(dp[0], -0x3f3f3f3f, sizeof(dp[0]));
        dp[0][0] = 0;
        for (i=1; i<=n; i++)
        {
            cur = rods[i-1];
            for (j=0; j<=5000; j++)
            {
                dp[i][j] = dp[i-1][j];      // case 0: rods[i-1] is not used
                if (j >= cur)
                {
                    dp[i][j] = max(dp[i][j], dp[i-1][j-cur] + cur); // case 1: assign rods[i-1] to "big"
                }
                if (j + cur <= 5000)
                {
                    dp[i][j] = max(dp[i][j], dp[i-1][j+cur]);     // case 2: assign rods[i-1] to "small"
                }
                if (cur > j)
                {
                    dp[i][j] = max(dp[i][j], dp[i-1][cur-j]+j);     // case 3: "small" and "big" swaps after assigning rods[i-1] to "big"
                }
            }
            
        }
        return dp[n][0];
    }
};

猜你喜欢

转载自blog.csdn.net/da_kao_la/article/details/85085276
Q4