本题我试过很多方法,最开始的思路是,一个娃娃可以套另一个娃娃,这种偏序关系可以建图。找出图中最长的路径,然后把那些点删掉,再找出最长的路径,删掉,直至图中没有点,删除的次数就是答案,可是这样会超时。第二个想法差不多,按照w+h的值递增的顺序对娃娃排序,然后用nlogn算法找出lis数组。然后利用lis数组不断的删除最长的子序列。其实和第一种思路差不多,但是还是超时。第三种就是按照w+h递减的顺序排序,然后从前往后找的第一个娃娃肯定就是答案中放在最外面的,不断的往后扫描,找到第一个能装进去的,这个娃娃的规格肯定和他最接近(贪心),就删除它,一直扫描到末尾。不断重复直至删除所有娃娃,复杂度n^2,还是超时。最后看了网上的博客,才能ac。

假设最后的答案是n,那么所有的娃娃都可以被套进那n个最大的娃娃中,并且这n个娃娃有一个特点,就是它们不能相互嵌套。那么我们是否可以猜测输入的娃娃中两两不能相互嵌套的娃娃数目就是答案呢?事实证明这个想法是正确的。如果答案比n还要小,那么就意味着我们要将两个互相不能嵌套的娃娃互相嵌套,太荒谬了!如果答案比n大,假如是n+1。那么就有n+1个不能相互嵌套的娃娃,但是我们算出来的是n,不可能是n+1。即n就是最后的答案

那么如何找到两两不能相互嵌套的娃娃数目?首先按照w从大到小对娃娃排序,然后对于这些娃娃的h构成的序列,找出它的最长上升子序列,这个子序列的长度就是两两不能相互嵌套的娃娃数目。为什么呢因为最长上升子序列中,任意两个娃娃a,b都满足a.w>b.w  a.h<b.h 所以他们不能相互嵌套。

下面是代码具体实现:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <sstream>
#include <fstream>
#include <istream>
#include <ostream>
#include <complex>
#include <cstring>
#include <utility>
#include <cstdlib>
#include <cstdio>
#include <vector>
#include <string>
#include <cctype>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <list>
#include <new>
#include <set>
#include <map>using namespace std;const int maxn = 20000 + 5;
const int INF = 0x3f3f3f3f;
typedef long long int LL;
typedef vector<int> vec;
struct doll
{int w, h;bool operator < (const doll &rhs) const{//这里一定要注意如果w相等,要按照h递增的顺序//参考 50 40,40 30,40 20,30 10这组数据if (w != rhs.w)return w > rhs.w;else return h < rhs.h;}
};
doll a[maxn];
int lis[maxn], len;
int n;void Binary_insert(int d)//二分查找第一个大于d的元素(注意不是大于等于),将其替换成d
{int l = 1, h = len, m;while(l <= h){m = (l + h) / 2;if(d < lis[m])h = m - 1;else l = m + 1;}lis[l] = d;
}int main()
{//freopen("1.txt", "r", stdin);int T;scanf("%d", &T);while (T--){int n;scanf("%d", &n);for (int i=0; i<n; i++)scanf("%d%d", &a[i].w, &a[i].h);sort(a, a+n);len = 0;lis[++len] = a[0].h;for (int i=1; i<n; i++)//求lis长度{if (a[i].h >= lis[len])//注意是>=不是大于lis[++len] = a[i].h;elseBinary_insert(a[i].h);}printf("%d\n", len);}return 0;
}

本题用的不是纯正的LIS,因为我们求的不是严格的单调递增,而是非递减序列。计算时>=末尾元素值的时候就可以接在末尾,<末尾时,要在lis数组中找到第一个大于它的元素,而不是大于等于,之前我用lower_bound函数一直wa。

EOJ1765 Nested Dolls 最长上升子序列相关推荐

  1. hdu 1677 Nested Dolls 子串

    题目: A - Nested Dolls Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64 ...

  2. 最长公共子序列(LCS)问题 Longest Common Subsequence 与最长公告字串 longest common substr...

    问题描述:字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列.令给定的字符序列X="x0,x1,-,xm-1",序列Y=& ...

  3. 最长连续子序列nlogn算法

    最长上升子序列(LIS)长度的O(nlogn)算法 标签: 算法search优化存储 2012-04-18 19:38 14031人阅读 评论(5) 收藏 举报  分类: 资料学习(15)  解题报告 ...

  4. leetcode-300 最长上升子序列

    题目描述: 给定一个无序的整数数组,找到其中最长上升子序列的长度. 示例: 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是 [2,3,7,101],它的长度 ...

  5. 【动态规划】最长公共子序列与最长公共子串

    1. 问题描述 子串应该比较好理解,至于什么是子序列,这里给出一个例子:有两个母串 cnblogs belong 比如序列bo, bg, lg在母串cnblogs与belong中都出现过并且出现顺序与 ...

  6. POJ 3080 多个串最长公共子序列

    求多个串最长公共子序列,字典序最小输出.枚举剪枝+kmp.比较简单,我用find直接查找16ms #include<iostream> #include<string> #in ...

  7. java实现最长连续子序列_最长公共子序列 ||

    问题:在 前一篇文章 最长公共子序列 | 的基础上要求将所有的最长公共子序列打印出来,因为最长公共子序列可能不只一种. 难点:输出一个最长公共子序列并不难,难点在于输出所有的最长公共子序列,我们需要在 ...

  8. 动态规划——最长上升子序列问题 两种角度及优化算法

    最长上升子序列 OpenJ_Bailian - 2757 一个数的序列 bi,当 b1 < b2 < ... < bS的时候,我们称这个序列是上升的.对于给定的一个序列( a1, a ...

  9. 动态规划—最长公共子序列问题 HDU-1159 Common Subsequence

    动态规划-最长公共子序列问题 Common Subsequence [ HDU - 1159 ] A subsequence of a given sequence is the given sequ ...

最新文章

  1. 国庆双节长假旅游出行必装的手机软件
  2. OneAPM大讲堂 | 提高JavaScript性能的30个技巧
  3. 以太坊测试链环境node.js版本
  4. 在.NetCore中使用Myrmec检测文件真实格式
  5. 2-6 基于SpringBoot的SpringSecurity环境快速搭建与验证
  6. 单E1光端机,V.35光端机,以太网光端机介绍及技术指标详解
  7. Swift--控制流与oc不同的地方
  8. 利用指针编程实现:删除一个字符串中的所有空格 c语言,C语言必考100题解析汇报...
  9. dlib 怎么安装vs2017_win10中的dlib库安装过程
  10. java 某个字符在字符串中出现的所有位置_Java面试常考核心概念
  11. 已知前序中序求层序 c语言递归,二叉树的遍历:前序,中序,后序,层序--包括递归和非递归实现...
  12. html介绍班级,班级介绍词 展示班级风采
  13. K8S_Google工作笔记0004---平台规划和部署方式介绍_搭建k8s集群准备
  14. linux gnu主要精神,最符合GNU精神的Linux发行版gnewsense
  15. selenium打开浏览器报错问题
  16. Windows 10正式版官方原版ISO镜像下载汇总!!!
  17. webui 通过提示词矩阵的文本框功能添加负面标签
  18. oracle数据库常用操作
  19. Packet Data Convergence Protocol (PDCP)阅读笔记
  20. matlab定积分怎么输入,Matlab计算定积分的操作内容讲解

热门文章

  1. 学习FBTT_EP(电警)
  2. 基于leaflet编写的经纬线网格绘制react插件
  3. Aerospike之路
  4. hdp修改服务器,hdp直播对接服务器地址
  5. 关于腾讯weibo获取头像的问题
  6. 公司邮箱怎么登陆?域名邮箱怎么登陆?手机如何登陆企业邮箱?
  7. 海康威视无线摄像头安装调试
  8. 回顾张柏芝和谢霆锋恩爱甜蜜合影(组图)
  9. 一个有节操的Android视频播放器JieCaoVideoPlayer
  10. 基于神经网络的毕设题目_自动化毕业设计题目