最长递增子序列(动态规划)

#include <bits/stdc++.h>

using namespace std;

int getValue(deque<int> d, list<int> temp) {
    if (d.size() < 2)
        return d.size();
    temp.emplace_back(d[0]);
    for (int i = 1; i < d.size(); i++)
        if (d[i] > *(--temp.end())) temp.emplace_back(d[i]);
        else {
            auto it = lower_bound(temp.begin(), temp.end(), d[i]);
            auto iter = temp.erase(it);
            temp.insert(iter, d[i]);
        }

    return temp.size();
}

void final(deque<int> d, list<int> temp) {
    int maxLen = getValue(d, temp);
    temp.emplace_back(d[0]);
    for (int i = 1; i < d.size(); i++)
        if (d[i] > *(--temp.end())) {
            temp.emplace_back(d[i]);
            if (temp.size() == maxLen)break;
        } else {
            auto it = lower_bound(temp.begin(), temp.end(), d[i]);
            auto iter = temp.erase(it);
            temp.insert(iter, d[i]);
        }
    for (auto it:temp)
        printf("%d ", it);
}

int main() {
    deque<int> d;
    int num;
    while (scanf("%d", &num), num)
        d.emplace_back(num);
    list<int> temp;
    //temp数组,d{2,1,5,3,6,4,8,9,7}
    //temp[i]即从d数组中选取i+1个元素构成递增序列(必须从小到大选,可跳过的选择)
    //假设此时i为2,则会有很多种排列方式(递增序列)
    //则temp[i]的值为(所有排列(在i为2的条件下)中最右端的元素(即每种排列方式的最右端数据即最大的数据))  最小的元素
    //则i为2时有以下几种排列方式
    //2 5 6, 2 5 8, 2 5 9, 2 5 7
    //1 5 6, 1 5 8, 1 5 9, 1 5 7
    //2 3 6, 2 3 4, 2 3 8, 2 3 9, 2 3 7
    //1 3 6, 1 3 4, 1 3 8, 1 3 9, 1 3 7
    //则所有最右端数据有6,8,9,7,4
    //所以temp[2]=4
    //temp[0]即为一个元素的最小值
    final(d, temp);

    return 0;
}

#include <bits/stdc++.h>

using namespace std;

int getValue(deque<int> d, int *temp) {
    if (d.size() < 2)
        return d.size();
    temp[0] = d[0];
    int len = 1;
    for (int i = 1; i < d.size(); i++)
        d[i] > temp[len - 1] ? temp[len++] = d[i] : ({
            int index = lower_bound(temp, temp + len, d[i]) - temp;
            temp[index] = d[i];
        });
    return len;
}

void final(deque<int> d, int *temp) {
    int maxLen = getValue(d, temp);
    temp[0] = d[0];
    int len = 1;
    for (int i = 1; i < d.size(); i++)
        if (d[i] > temp[len - 1]) {
            temp[len++] = d[i];
            if (len == maxLen)
                break;
        } else {
            int index = lower_bound(temp, temp + len, d[i]) - temp;
            temp[index] = d[i];
        }

    for (int i = 0; i < len; i++)
        printf("%d ", temp[i]);
}

int main() {
    deque<int> d;
    int num;
    while (scanf("%d", &num), num)
        d.emplace_back(num);
    int temp[d.size()];
    //temp数组,d{2,1,5,3,6,4,8,9,7}
    //temp[i]即从d数组中选取i+1个元素构成递增序列(必须从小到大选,可跳过的选择)
    //假设此时i为2,则会有很多种排列方式(递增序列)
    //则temp[i]的值为(所有排列(在i为2的条件下)中最右端的元素(即每种排列方式的最右端数据即最大的数据))  最小的元素
    //则i为2时有以下几种排列方式
    //2 5 6, 2 5 8, 2 5 9, 2 5 7
    //1 5 6, 1 5 8, 1 5 9, 1 5 7
    //2 3 6, 2 3 4, 2 3 8, 2 3 9, 2 3 7
    //1 3 6, 1 3 4, 1 3 8, 1 3 9, 1 3 7
    //则所有最右端数据有6,8,9,7,4
    //所以temp[2]=4
    //temp[0]即为一个元素的最小值
    final(d, temp);

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值