swust oj 585--倒金字塔(LIS最长不下降子序列)

题目链接:http://acm.swust.edu.cn/problem/585/

Time limit(ms): 3000      Memory limit(kb): 65535

SWUST国的一支科学考察队到达了举世闻名的古埃及金字塔。 
关于金字塔的建造一直是一个未解之谜, 有着“西方史学之父”之称的希罗多德认为,金字塔的建造是人力和牲畜,花费20 年时间从西奈半岛挖掘天然的石头运送到埃及堆砌而成。也有不少人认为是外星人修建的。人们发现胡夫金字塔的经线把地球分成东、西两个半球,它们的陆地面积是相等的,这种“巧合”大概是外星人选择金字塔建造地点的用意。法国化学家戴维·杜维斯则认为,建造金字塔的巨石不是天然的,而是人工浇筑的。 
SWUST 国科考队的队员们正准备研究戴维·杜维斯提出的假说。为了研究这种假说,他们需要用到“倒金字塔模型”。所谓倒金字塔模型,即金字塔由N 层人工浇筑的巨石堆砌而成,非底层的任意一层巨石的长度和宽度都必须要小于等于它下面的一层巨石的长度和宽度。 
现在,科考队队员们打算用手里仅有N 块木板去模拟这个倒金字塔模型。请计算出科考队队员们能够构建的倒金字塔模型的最大高度。

Description

测试数据的第1 行,为一个正整数N(N <= 100000),表示科考队队员们手里一共有N 块木板。 
接下来N 行,每行两个数:a,b( a, b <= 100000),分别表示一块木板的长度与宽度。

Input

只有一个正整数,为最多可以堆叠的倒金字塔的高度。所有的木板厚度均为1。

Output

1

2

3

4

5

3

3 2

1 1

2 2

Sample Input

1

2

3

Sample Output

解题思路:先按照一个坐标为基准升序排序,然后求最长不下降子序列(LIS),

这里由于测试数据较多(100000),在dp时采用二分查找,这样T(n)=O(nlog2n).~~

关于LIS可以戳戳这里:http://www.cnblogs.com/zYx-ac/p/4296704.html

代码如下:

 1 #include <iostream>
 2 #include <algorithm>
 3 using namespace std;
 4
 5 struct node{
 6     int x, y;
 7     bool operator<(const node &tmp)const{
 8         if (x != tmp.x)
 9             return x < tmp.x;
10         return y < tmp.y;
11     }
12 }tower[100005];
13
14 int n, len, dp[100005];
15
16 int binary_search(int key, int low, int high){
17     while (low < high){
18         int mid = (low + high) >> 1;
19         if (key >= dp[mid])
20             low = mid + 1;
21         else  high = mid;
22     }
23     return low;
24 }
25
26 int main(){
27     int i, j;
28     while (cin >> n){
29         for (i = 0; i < n; i++) cin >> tower[i].x >> tower[i].y;
30         sort(tower, tower + n);
31         dp[1] = tower[0].y, len = 1;
32         for (i = 1; i < n; i++){
33             if (dp[len] <= tower[i].y)  j = ++len;
34             else
35                 j = binary_search(tower[i].y, 1, len + 1);
36             dp[j] = tower[i].y;
37         }
38         cout << len << endl;
39     }
40     return 0;
41 }

时间: 2024-10-11 22:50:45

swust oj 585--倒金字塔(LIS最长不下降子序列)的相关文章

LIS [SWUST OJ 585] 倒金字塔

倒金字塔(0585) Time limit(ms): 3000 Memory limit(kb): 65535 Submission: 208 Accepted: 48 Description SWUST国的一支科学考察队到达了举世闻名的古埃及金字塔. 关于金字塔的建造一直是一个未解之谜, 有着“西方史学之父”之称的希罗多德认为,金字塔的建造是人力和牲畜,花费20 年时间从西奈半岛挖掘天然的石头运送到埃及堆砌而成.也有不少人认为是外星人修建的.人们发现胡夫金字塔的经线把地球分成东.西两个半球,它

LIS——最长不下降子序列

输入一个n,以及n个数据,输出最长的不下降的子序列 大意: 有两种思路: 1.O(n^2)想法 用一个num来记录以该数字为末数字的长度 用一个if限制两个条件,后面小于前面并且后面的长度大于前面的长度+1那么说明需要更新了,最后只要遍历所有的数字在num中看以那个数字为开始点的长度最长.这个比较好理解 #include<cstdio> const int MAX = 150; int a[MAX],num[MAX]; int main() { int n; scanf("%d&qu

SPOJ 3943 - Nested Dolls 最长不下降子序列LIS(二分写法)

现在n(<=20000)个俄罗斯套娃,每个都有宽度wi和高度hi(均小于10000),要求w1<w2并且h1<h2的时候才可以合并,问最少能剩几个. [LIS]乍一看跟[这题]类似,但是仔细看是有区别的,其实就相当于上一题多次求LIS,每次求完LIS后把得到的序列删去,然后重新求LIS,最后输出求LIS的次数,我一开始这样写,果然就TLE了.还是要另辟蹊径. 首先用贪心思想,先按照wi从大到小排序,wi相等的情况下hi从小到大,然后求最长不下降子序列(注意可以等于).输出其长度即可. 想

最长不下降子序列(LIS)

最长上升子序列.最长不下降子序列,解法差不多,就一点等于不等于的差别,我这里说最长不下降子序列的. 有两种解法. 一种是DP,很容易想到,就这样: 1 REP(i,n) 2 { 3 f[i]=1; 4 FOR(j,0,i-1) 5 if(a[j]<=a[i]) f[i]=max(f[i],f[j]+1); 6 } DP是O(n^2)的,我感觉已经不错了不过还有超碉的nlogn的方法. nlogn的方法: 用栈和二分查找. 遇到一个元素a[i],若它不小于栈顶s[top],直接入栈:若大于栈顶,则

动态规划——最长不下降子序列(LIS)

最长不降子序列是这样一个问题: 下面介绍动态规划的做法. 令 dp[i] 表示以 A[i] 结尾的最长不下降序列长度.这样对 A[i] 来说就会有两种可能: 如果存在 A[i] 之前的元素 A[j] (j<i),使得 A[j]≤A[i] 且 dp[j]+1>dp[i],那么就把 A[i] 跟在以 A[j] 结尾的 LIS 后面,形成一条更长的不下降子序列(令 dp[i]=dp[j]+1). 如果 A[i] 之前的元素都比 A[i] 大,那么 A[i] 就只好自己形成一条 LIS,但是长度为 1

toj 4071 最长不下降子序列nlogn解法

题目描述:给出2D空间中的n只鸟的坐标,射手对其进行射击,要求射击的鸟的坐标越来越大,即对于第i和第i+1只鸟,要求满足:xi<=xi+1 && yi <= yi+1.求最多能射击多少只鸟. 思路:将所有点按照x坐标排序,x坐标相同则按照y坐标排序.则x方向上可以满足限制,对y方向上求最长不下降子序列即可.由于数据量较大,需要采取nlogn的优化算法. 1 #include <algorithm> 2 #include <iostream> 3 #inc

「网络流24题」最长不下降子序列问题

传送门:>Here< 题意: 给定正整数序列$x_1,...,x_n$ (1)计算其最长不下降子序列的长度s. (2)计算从给定的序列中最多可取出多少个长度为s的不下降子序列. (3)如果允许在取出的序列中多次使用$x_1$和$x_n$,则从给定序列中最多可取出多少个长度为$s$的不下降子序列. 思路分析 题意首先就很坑:注意第二问中的取出二字,意味着一个数字最多只能存在于一个LIS中.所以才会有第三问的假设 第一问很简单,直接暴力$O(n^2)$就好了 后面的两问需要借助于网络流.很容易想到

P2766 最长不下降子序列问题

\(\color{#0066ff}{题目描述}\) ?问题描述: 给定正整数序列x1,...,xn . (1)计算其最长不下降子序列的长度s. (2)计算从给定的序列中最多可取出多少个长度为s的不下降子序列. (3)如果允许在取出的序列中多次使用x1和xn,则从给定序列中最多可取出多少个长度为s的不下降子序列. ?编程任务: 设计有效算法完成(1)(2)(3)提出的计算任务. \(\color{#0066ff}{输入格式}\) 第1 行有1个正整数n,表示给定序列的长度.接下来的1 行有n个正整

[网络流24题]最长不下降子序列问题

[luogu 2766] 最长不下降子序列问题 传送门 第一问: \(O(n^2)\) 的DP求LIS 为了下面叙述方便,我们将DP过程讲一遍 子状态:dp[i]表示以a[i]结尾的LIS长度 初始条件:dp[i]=1 状态转移方程:\(dp[i]=dp[j]+1(j<i,a[j]\leq a[i])\) 第二问: 我们发现若a[j]加上a[i]可以构成一个不下降子序列,则\(j<i,a[j] \leq a[i]\) 又发现每个元素只能在一个序列中,考虑拆点 建图方法: 原点S=0,T=2n+