程序员面试金典: 9.11 排序与查找 11.6叠罗汉问题-------动态规划

这是一个关于马戏团叠罗汉的问题,要求找到最多能叠多少人,同时上面的人要比下面的人矮一点、轻一点。通过动态规划,将问题转化为最长递增子序列问题,并在高度和体重两个属性上进行排序,从而找到最优解。代码中定义了People结构体,根据高度和体重进行比较,然后使用动态规划数组dp和路径数组paths来求解,最终输出最长递增子序列的长度和具体路径。
#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个元素
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值