leetcode 动态规划 最大递增子序列 C++

题目:

给定一个无序的整数数组,找到其中最大递增子序列。
示例:
输入: vector list {10, 11, 12, 13, 1, 2, 3, 4, 5}
输出: 1, 2, 3, 4, 5

显然,与常见的动态规划题目类似,首先需要将复杂问题分解为小问题。来了解一下最优子序列的概念(自创概念,不知道是否要这么叫)。

指定个数的最优子序列:

上述list中,若指定个数为1的子序列,那么每个元素都可以单独为一个子序列,但是在递增排序过程中,子序列有优劣之分,比如个数为1的递增子序列{1} 和{13},都可看做是个数为1的递增子序列,但是{1}比{13}要小,在递增排序中{1}更占据优势,更有竞争力,比如,后续检测到元素{2}需要组成个数为2的递增子序列,那么{1,2}能成为更长的递增子序列,而{13,2}无法组成递增子序列。所以,递增子序列中,最大的值越小,其递增子序列越优秀。

如果输入的 list 为 {10, 11, 12, 13},那么其各个数递增最优子序列为:
{10}							//个数为1的最优递增子序列
{10, 11}						//个数为2的最优递增子序列
{10, 11, 12}					//个数为3的最优递增子序列
{10, 11, 12, 13}				//个数为4的最优递增子序列
但如果输入的list为{10, 11, 12, 13, 1, 2},那么其各个数递增最优子序列为:
{1}							//个数为1的最优递增子序列,读取到{1}时,用{1}替换了原有的最优子序列
{1, 2}						//个数为2的最优递增子序列,同理,替换为{1, 2}
{10, 11, 12}				//个数为3的最优递增子序列
{10, 11, 12, 13}			//个数为4的最优递增子序列
无							//个数为5的最优递增子序列
无							//个数为6的最优递增子序列

代码解析:

  1. table向量即为 个数为n的最优递增子序列向量。
  2. 通过逐个读取list 中的元素,并且保持上述最优原则,不停的更新table向量中的各元素,维持其最优状态。最终将获得list 的最长最优递增子序列

代码:

int main(void)
{
    vector<int> list {10, 11, 12, 13, 1, 2, 3, 4, 5};
    vector<vector<int>> table;  //当前索引i情况下的各个数子串最优解序列
    vector<int> temp;
    int len = list.size();
    for(int i = 0;  i < len; i++)
    {
        if(i == 0)
        {
            temp.push_back(list[i]);
            table.push_back(temp);
            continue;
        }
        temp = table.back();
        if(list[i] > temp.back())
        {
            temp.push_back(list[i]);
            table.push_back(temp);
        }
        else
        {
            int listnum = table.size();
            for(int j = 0; j < listnum; j++)
            {
                if(list[i] <= table[j].back())
                {
                    if(j == 0)
                    {
                        temp.clear();
                        temp.push_back(list[i]);
                        table[j] = temp;
                        break;
                    }
                    else
                    {
                        temp = table[j-1];
                        temp.push_back(list[i]);
                        table[j] = temp;
                        break;
                    }
                }
            }
        }

    }
    for(int i = 0; i < table.size(); i++)
    {
        for(int j = 0; j < table[i].size(); j++)
        {
            cout << table[i][j] << ' ';
        }
        cout << endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值