目录
牛客_马戏团(模拟最长上升子序列)
搜狐员工小王最近利用假期在外地旅游,在某个小镇碰到一个马戏团表演,精彩的表演结束后发现团长正和大伙在帐篷前激烈讨论,小王打听了下了解到, 马戏团正打算出一个新节目“最高罗汉塔”,即马戏团员叠罗汉表演。考虑到安全因素,要求叠罗汉过程中,站在某个人肩上的人应该既比自己矮又比自己瘦,或相等。 团长想要本次节目中的罗汉塔叠的最高,由于人数众多,正在头疼如何安排人员的问题。小王觉得这个问题很简单,于是统计了参与最高罗汉塔表演的所有团员的身高体重,并且很快找到叠最高罗汉塔的人员序列。 现在你手上也拿到了这样一份身高体重表,请找出可以叠出的最高罗汉塔的高度,这份表中马戏团员依次编号为1到N。
解析代码
体重升序排列, 体重相同时,按身高降序排列 接下来就是按照身高数据进行最大升序子序列的长度。
注意:此题中,体重相同时,只有身高也相同才可以站在自己肩上,比自己矮是不能站在自己肩上的。所以如果想要排除体重相同时,只看身高相等的,不看身高矮的,所以身高降序排列求最大升序子序列的长度,采用动态规划:
- 状态F(i): 以第i个数据结尾的升序子序列的最大长度
- F(i) = max(F(i), F(j) + 1), 其中 j < i,其arr[j] <= arr[i]
- 状态初始值:F(i) = 1
- 返回值: max(F(i))
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;
struct node
{
int _w;
int _h;
bool operator<(const node& obj)
{
if (_w != obj._w) // 体重升序
return _w <= obj._w;
else // 身高降序
return _h > obj._h;
}
};
int getMaxLength(vector<node>& v, int n)
{
// 首先排序
sort(v.begin(), v.end());
vector<int> maxLength(n, 1);
int ret = 0;
// 求最大升序子序列的长度
for (int i = 1; i < n; ++i)
{
for (int j = 0; j < i; ++j)
{
if (v[j]._h <= v[i]._h)
{
maxLength[i] = max(maxLength[i], maxLength[j] + 1);
}
}
// 更新最大值
ret = max(ret, maxLength[i]);
}
return ret;
}
int main()
{
int n;
while (cin >> n)
{
vector<node> v(n);
int num = 0;
// 输入数据
for (int i = 0; i < n; ++i)
{
cin >> num >> v[i]._w >> v[i]._h;
}
cout << getMaxLength(v, n) << endl;
}
return 0;
}