nyoj 16 最长上升子序列变形

经典矩形嵌套问题,先排序再求LIS。

需要注意在枚举j的时候x和y都要小于i才行。

 1 #include <algorithm>
 2 #include <cstdio>
 3 using namespace std;
 4
 5 const int N = 1000;
 6 int dp[N];
 7
 8 struct Node
 9 {
10     int x, y;
11     bool operator < ( const Node & o ) const
12     {
13         if ( x != o.x ) return x < o.x;
14         return y < o.y;
15     }
16 } node[N];
17
18 int main ()
19 {
20     int t;
21     scanf("%d", &t);
22     while ( t-- )
23     {
24         int n;
25         scanf("%d", &n);
26         for ( int i = 0; i < n; i++ )
27         {
28             scanf("%d%d", &node[i].x, &node[i].y);
29             if ( node[i].x > node[i].y )
30             {
31                 swap( node[i].x, node[i].y );
32             }
33         }
34         sort( node, node + n );
35         int ans = -1;
36         for ( int i = 0; i < n; i++ )
37         {
38             dp[i] = 1;
39             for ( int j = 0; j < i; j++ )
40             {
41                 if ( node[j].x < node[i].x && node[j].y < node[i].y )
42                 {
43                     dp[i] = max( dp[i], dp[j] + 1 );
44                 }
45             }
46             ans = max( ans, dp[i] );
47         }
48         printf("%d\n", ans);
49     }
50     return 0;
51 }

也可以根据矩形的嵌套关系建图,然后用拓扑排序+dp或者是逆向建图记忆花搜索来求解。

时间: 2025-01-07 03:10:10

nyoj 16 最长上升子序列变形的相关文章

HDU 1160 FatMouse&#39;s Speed 动态规划 记录路径的最长上升子序列变形

题目大意:输入数据直到文件结束,每行两个数据 体重M 和 速度V,将其排列得到一个序列,要求为:体重越大 速度越低(相等则不符合条件).求这种序列最长的长度,并输出路径.答案不唯一,输出任意一种就好了. 题目思路:这是个最长上升子序列的问题,我们按W的升序进行排序,若W相等则按V的降序排序.用Pre[]记录当前点的前驱节点,Last记录序列最后一个点,maxn记录最长长度,完成动规后可根据Last和Pre[]输出路径. #include<cstdio> #include<stdio.h&

编程之美2.16 最长递增子序列

      这道题目要求返回一个数字,这个数字代表一个数组中最长的递增子序列,当然,不要求这个序列是连续的,比如,有这样一个数组:{1, 3,5,7, 2, 9},那么这个数组的最长递增子序列就是5,即1,  3,  5,  7,9       解决这道题目的思想就是:后面的数字只要是大于前面递增子序列的最大值,那么,它就一定大于前面所有的序列,既然需要知道前面保存的序列,那么,我们这里就需要一个辅助数组,数组中存储的就是"最小的连续递增子数组",我们操作这个数组时,需要遵循两个规律:

nyoj 36 最长公共子序列 【DP】

今天听了老师讲的最长公共子序列,就拿以前做过的题又做了一遍... 我用的是最简单普通的方法, 代码: #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; int dp[1005][1005]; int main() { char a[1005], b[1005]; int t; scanf("%d", &t); while(t --){ s

vijos P1028 最长上升子序列变形题

#include<iostream> #include<cstdio> #include<cstring> #include<map> #include<string> #include<vector> #include<algorithm> using namespace std; bool judge(const string &aa,const string &bb) { for(int i=0;i&

【HDU】5256 序列变换(最长上升子序列变形)

如果a[i]和a[j]想不变,需要满足的条件就是 a[j] - a[i] > j - i 也就是a[i] - i < a[j] - j 比如1 4 2 就不满足,所以1和2之间一定有一个需要改变 所以我们对所有a[i] - i求其最长上升子序列就可以了 #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn = 100005; con

poj1159--Palindrome(dp:最长公共子序列变形 + 滚动数组)

Palindrome Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 53414   Accepted: 18449 Description A palindrome is a symmetrical string, that is, a string read identically from left to right as well as from right to left. You are to write a

NYOJ 36 最长公共子序列 (还是dp)

这个好多算法书上都有,不仅限于<算法导论> 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描写叙述 咱们就不拐弯抹角了,如题.须要你做的就是写一个程序,得出最长公共子序列. tip:最长公共子序列也称作最长公共子串(不要求连续),英文缩写为LCS(Longest Common Subsequence). 其定义是.一个序列 S ,假设各自是两个或多个已知序列的子序列,且是全部符合此条件序列中最长的.则 S 称为已知序列的最长公共子序列. 输入 第一行给出一个整数N(0

UVA 10723--Cyborg Genes+最长公共子序列变形

题目链接:点击进入 首先对于长度最短的情况是很容易确定的,只需要用两个字符串的长度和减去他们的最长公共子序列长度.然后比较麻烦的就是合乎要求的字符串的个数,其实我们也可以用类似于最长公共子序列的dp来求. 设dp[i][j]表示str1的前i个字符和str2的前j个字符所得到的满足要求的字符串,则如果str[i]==str[j],则dp[i][j]+=dp[i-1][j-1]; 否则就要根据i,j这两个位置上的最长公共子序列长度进行讨论,具体见代码. 代码如下: #include<iostrea

hdu1243(最长公共子序列变形)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1243 分析:dp[i][j]表示前i个子弹去炸前j个恐怖分子得到的最大分.其实就是最长公共子序列加每个字母值为1,这里每个字母代表的值变化了一下. 状态转移方程:if(s1[i-1]==s2[j-1])dp[nxt][j]=dp[cur][j-1]+val[s1[i-1]];                              else  dp[nxt][j]=max(dp[nxt][j-1]