题目描述
书籍的长、宽都是整数对应 (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;
}