29. 书籍叠放

84 阅读2分钟

题目描述

书籍的长、宽都是整数对应 (l,w)。如果书 A 的长宽度都比 B 长宽大时,则允许将 B 排列放在 A 上面。

现在有一组规格的书籍,书籍叠放时要求书籍不能做旋转,请计算最多能有多少个规格书籍能叠放在一起。

输入描述

输入:books = [[20,16],[15,11],[10,10],[9,10]]

说明:总共4本书籍,第一本长度为20宽度为16;第二本书长度为15宽度为11,依次类推,最后一本书长度为9宽度为10.

输出描述

输出:3

说明: 最多3个规格的书籍可以叠放到一起, 从下到上依次为: [20,16],[15,11],[10,10]

用例

输入 [[20,16],[15,11],[10,10],[9,10]]
输出 3
说明 最多3个规格的书籍可以叠放到一起,从下到上依次为:[20,16]、[15,11]、[10,10]

思路

首先按照长度升序排序,长度相同则宽度降序,忽略长度维度,这时就变成求,现在这个数组宽度维度的最大递增子序列。

动态规划:

dp[i] 以width[i] 结尾最长递增子序列的长度。 dp[1] = 1;

dp[i] = max(dp[i], dp[j] + 1) && width[i] > width[j] && j < i

#include <iostream>
#include <vector>
#include <sstream>
#include <algorithm>
using namespace std;

vector<string> split(string s, char c)
{
    vector<string> res;
    stringstream ss(s);
    string tmp;
    while (getline(ss, tmp, c))
    {
        res.push_back(tmp);
    }
    return res;
}

int lengthOfLIS(const vector<int> &books)
{
    // 以nums[i]结尾的最长递增数组
    vector<int> dp(books.size(), 1);

    int ans = dp[0];

    for (int i = 1; i < books.size(); i++)
    {
        for (int j = 0; j < i; j++)
        {
            if (books[i] > books[j])
            {
                dp[i] = max(dp[i], dp[j] + 1);
            }
        }
        ans = max(ans, dp[i]);
    }
    return ans;
}

int main()
{
    string books;
    getline(cin, books);
    books.pop_back();
    books.erase(0, 1);
    vector<string> temp = split(books, ',');
    vector<pair<int, int>> booklist;
    for (int i = 0; i < temp.size(); i += 2)
    {
        string c = temp[i].erase(0, 1);
        temp[i + 1].pop_back();
        string k = temp[i + 1];
        booklist.push_back(make_pair(stoi(c), stoi(k)));
    }

    sort(booklist.begin(), booklist.end(), [](const pair<int, int> &a, const pair<int, int> &b)
         { if (a.first == b.first) return a.second > b.second;
         return a.first < b.first; });

    vector<int> width(booklist.size());
    for (int i = 0; i < booklist.size(); i++)
    {
        width[i] = booklist[i].second;
    }
    cout << lengthOfLIS(width);
    return 0;
}