#include <iostream>
#include <stdio.h>
#include <vector>
#include <algorithm>
using namespace std;
/*
问题:有个马戏团正在设计叠罗汉的表演节目,一个人要站在另一个人的肩膀上。出于实际和美观的考虑,在
上面的人要比下面的人矮一点、轻一点。已知马戏团每个人的高度和重量,请编写代码计算叠罗汉最多
能叠几个人。
分析:这不是之前“推箱子”的题目吗。之前是用递归做的。假设人有高度h和重量w两个属性,可以尝试将每个人
放在最底部,注意这里求的是人的个数,更简单。
输入:
5(人的个数n,接下来有n行,每一行第一个是人的高度,第二个是人的重量)
180 75
175 80
178 70
170 78
160 76
输出:
160 76,170 78,175 80,(选中的人)
3(选中的人的个数)
关键:
1
书上解法:这是最长递增子序列题目的翻版。最长递增子序列是在一个已知的序列{a1,a2,...,an}中,取出若干数组成心得序列{ai1,ai2,..,aim},
其中下标i1,i2,...,im保持递增,即新增数列中的各个数之间依旧保持原数列 中的先后顺序,那么称新的序列为原序列的一个子序列。
若在序列中,下标ix > iy时,aix > aiy,称这个子序列为原序列的一个递增子序列。
设d[i]为以ai结尾的最长递增子序列,则d[x]=max{1 , d[i] + 1 | i < x }
d[1] = 1
遍历数组d,取出最大的数即可。
但对比上一题目,如何排序,这是有两种属性。
先对高度进行排序,高度相同的情况下再按照体重排序,寻找出在高度已排序的序列中体重的最长递增子序列。
高度属性(排序) 等同于 用于确定最长递增子序列中原有顺序
体重 等同于 用于生成最长递增子序列的度量
动态规划中设置状态转移方程的一个技巧:设置的是前缀和,比如d[i]不是表示的第i个元素的结果,而是表示以第i个元素