lintcode 最长上升连续子序列 II(二维最长上升连续序列)

题目链接:http://www.lintcode.com/zh-cn/problem/longest-increasing-continuous-subsequence-ii/

最长上升连续子序列 II

  给定一个整数矩阵(其中,有 n 行, m 列),请找出矩阵中的最长上升连续子序列。(最长上升连续子序列可从任意行或任意列开始,向上/下/左/右任意方向移动)。

样例

给定一个矩阵

[
  [1 ,2 ,3 ,4 ,5],
  [16,17,24,23,6],
  [15,18,25,22,7],
  [14,19,20,21,8],
  [13,12,11,10,9]
]

返回 25

思路:记忆化搜索 + dp

  设Lics(num)表示以num开头的最长上升子连续序列的长度, 则Lics(A[x][y]) = max(Lics(A[x-1][y]), Lics(A[x][y-1]), Lics(x+1,y), Lics(x, y+1))+1;

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<deque>
#include<map>
using namespace std;

class Solution {
public:
    /**
     * @param A an integer matrix
     * @return  an integer
     */
    int n, m, maxL;
    int lics[1000][1000];
    int vis[1000][1000];
    int dir[4][2] = {{0, 1}, {1, 0}, {0,-1}, {-1,0}};
    int dfs(vector<vector<int>>& A, int x, int y){
        int maxLics = 0;
        vis[x][y] = 1;
        for(int i=0; i<4; ++i){
            int xx = x+dir[i][0];
            int yy = y+dir[i][1];
            if(xx<0 || yy<0 || xx>=n || yy>=m) continue;
            if(A[x][y] >= A[xx][yy]) continue;
            if(!vis[xx][yy])
                maxLics = max(maxLics, dfs(A, xx, yy));
            else
                maxLics = max(maxLics, lics[xx][yy]);
        }
        lics[x][y] = maxLics+1;
        if(maxL < lics[x][y]) maxL = lics[x][y];
        return lics[x][y];
    } 

    int longestIncreasingContinuousSubsequenceII(vector<vector<int>>& A) {
        n = A.size();
        if(n == 0) return 0;
        m = A[0].size();
        memset(lics, 0, sizeof(lics));
        memset(vis, 0, sizeof(vis));
        maxL = 0;
        for(int i=0; i<n; ++i)
            for(int j=0; j<m; ++j)
                if(!vis[i][j])
                    dfs(A, i, j);
        return maxL;
    }
};
/*
1 2 3 4 5
16 17 24 23 6
15 18 25 22 7
14 19 20 21 8
13 12 11 10 9
*/
时间: 2025-01-05 23:20:54

lintcode 最长上升连续子序列 II(二维最长上升连续序列)的相关文章

SGU 199 Beautiful People 二维最长递增子序列

题目链接: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=20885 题意: 求二维最长严格递增子序列. 题解: O(n^2)的算法很好想,不过这里会t掉,只能O(nlogn) 于是用二分来维护: 先把所有的数按x递增排序,x相同的按y递减排序(这里之所以要按y递减排序是因为为了写代码方便,递减的话你后面基本就只要考虑y的大小,如果不递减,你还要考虑x的大小的,具体的可以自己思考一下) 排完序之后我们接下来就只考虑y的大小

hdu1081 dp 二维矩阵求最大连续子矩阵

O(n^3) 必然要讨论每种情况,每行必然要讨论0~0,0~1,0~2,...i~j(0<=i<=j<n)的情况,每行的每种情况都是一个确定的数值,则把n个[f(i,j)]可以看作求一个一维的最长连续子序列,这样讨论每种i,j分部情况,求出对应的一维最长子序列,这些子序列取max,即为题目所要求的最大连续子矩阵 其实我们可以再输入的时候,就把a[i][j]确定为第i行前j个数之和,即为0~j的分步,这样我们以后讨论序列start~end时,只要a[k][end]-a[k][start-1

连续子数组(二维)的最大和

题目连接如下: http://www.acmerblog.com/max-sum-rectangle-in-a-matrix-5955.html 一维数组的连续子数组的最大和 题目:输入一个整型数组,数组里有正数也有负数.数组中一个或连续的多个整数组成一个子数组.求所有子数组的和的最大值.要求时间负责度为O(n). 假如输入数组为{1,-2,3,10,-4,7,2,-5},我们尝试从头到尾累加其中的正数,初始化和为0,第一步加上1,此时和为1,第二步加上-2,此时和为-1,第三步加上3,此时我们

[LeetCode] Longest Uncommon Subsequence II 最长非共同子序列之二

Given a list of strings, you need to find the longest uncommon subsequence among them. The longest uncommon subsequence is defined as the longest subsequence of one of these strings and this subsequence should not be any subsequence of the other stri

UVa 10285 Longest Run on a Snowboard(DP 二维最长递减子序列)

题意  输入一个城市的滑雪地图  你可以从高的地方滑到伤下左右低的地方  求这个城市的最长滑雪线路长度   即在一个矩阵中找出最长递减连续序列 令d[i][j]为以格子map(i,j)为起点的最长序列   则有状态转移方程d[i][j]=max{d[a][b]}+1  a,b为与i,j相邻且值比i,j小的所有点 #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #def

【模板】最长公共子序列(二维偏序)

给出1-n的两个排列P1和P2,求它们的最长公共子序列. 洛谷1439 1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 const int maxn=100010; 5 int n,x,ans,tmp,pos[maxn],t[maxn]; 6 void read(int &k){ 7 k=0; int f=1; char c=getchar(); 8 while(c<'0'||c>

[poj1088]滑雪(二维最长下降子序列)

解题关键:记忆化搜索 #include<cstdio> #include<cstring> #include<algorithm> #include<cstdlib> #include<iostream> #include<cmath> using namespace std; typedef long long ll; int d[102][102],n,m; int dp[102][102]; int dir[4][2]={0,1

最长公共子序列II.打印出最长公共子序列

#include<stdio.h> #include<string.h> #include<stack> #include<algorithm> using namespace std; #define N 1010 int dp[N][N]; char c; int main() { char a[N]; char b[N]; scanf("%s%s",a,b); int la=strlen(a); int lb=strlen(b);

最大子序列变形——二维带权值 O(n*n) HDU1069

#include <cstring> #include <iostream> #include <algorithm> using namespace std; int tmp[30][3]; int dp[100]; class Node { public: int x; int y; int h; bool operator <(const Node&n) const { if(x==n.x) return y<n.y; else return