首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >天池 在线编程 拿走瓶子(区间DP)

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

作者头像
Michael阿明
发布2021-02-19 12:46:02
发布2021-02-19 12:46:02
2460
举报

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++


本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/11/07 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 题目
  • 2. 解题
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档