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

文章目录

1. 题目

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

n<=500 
arr[i]<=1000

示例

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

来源:https://tianchi.aliyun.com/oj/141754208384739500/160296091929219254

2. 解题

  • 区间DP,dp[i][j] 表示区间 [i, j] 需要拿的最少次数
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++


我的CSDN博客地址 https://michael.blog.csdn.net/

长按或扫码关注我的公众号(Michael阿明),一起加油、一起学习进步!
Michael阿明

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Michael阿明

如果可以,请点赞留言支持我哦!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值