天池 在线编程 拿走瓶子(区间DP)

2021-02-19 12:46:02 浏览数 (1)

1. 题目

描述 有n个瓶子排成一列,用arr表示。 你每次可以选择能够形成回文连续子串的瓶子拿走,剩下的瓶子拼接在一起。 返回你能拿走所有的瓶子的最小次数

代码语言:javascript复制
n<=500 
arr[i]<=1000

示例

代码语言:javascript复制
例1:
输入:[1,3,4,1,5] 
输出:3 
说明:第一次先拿走[4],剩余[1,3,1,5]
第二次拿走[1,3,1],剩余[5]
第三次拿走[5]

例2:
输入:[1,2,3,5,3,1]
输出:2

2. 解题

  • 区间DP,dp[i][j] 表示区间 [i, j] 需要拿的最少次数
代码语言:javascript复制
class Solution {
public:
    /**
     * @param arr: the array of bottles
     * @return: the minimum number of times you can take all the bottles
     */
    int takeAwayTheBottle(vector<int> &arr) {
        // Write your code here.
        int n = arr.size();
        if(n == 0)
            return 0;
        vector<vector<int>> dp(n, vector<int>(n, INT_MAX));
        for(int i = 0; i < n; i  )
            dp[i][i] = 1;//初始化长度为1的区间
        for(int i = 1; i < n; i  )
            if(arr[i-1] == arr[i])//初始化长度为2的区间
                dp[i-1][i] = 1;
            else
                dp[i-1][i] = 2;
        for(int len = 2; len < n; len  )
        {	// 区间长度
            for(int i = 0; i len < n; i  )
            {
                int j = i len;
                if(arr[i] == arr[j])//左右端点相等
                    dp[i][j] = dp[i 1][j-1];
                for(int k = i; k < j; k  ) //左右端点 不相等,区间切开
                    dp[i][j] = min(dp[i][j], dp[i][k]   dp[k 1][j]);
            }
        }
        return dp[0][n-1];
    }
};

603ms C


0 人点赞