双端LIS问题:从一列数中筛除尽可能少的数使得从左往右看,这些数是从小到大再从大到小的。

来源:互联网 发布:网络问卷调查网站 编辑:程序博客网 时间:2024/04/28 14:11

从一列数中筛除尽可能少的数使得从左往右看,这些数是从小到大再从大到小的。

双端LIS问题(从两端做LIS操作)。我们只要在数组的两端进行一次LIS操作,对应的字串长度分别保存在dp[]和dp2[]中,这样我们只要使得dp[i]+dp2[i]-1最大,这个长度就是满足条件的最长字串。


// DoubleLIS.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include "stdio.h"#define N 10int dp[N];//表示从A[1]到A[i]中以A[i]结尾的最长上升子序列长度int dp2[N];//表示从A[1]到A[i]中以A[i]结尾的最长下降子序列长度int a[N] = {0,2,1,5,3,6,4,8,9,7};int LIS(int n)  //从左往右最长序列的长度{int ans = 1;int i, j;dp[1] = 1;for (i = 2; i < N; i++){int tmp = i;int max = 0;for (j = 1; j < i; j++){//从左向右搜索dp数组,若满足上升序列的条件//1.若a[i] > a[j]//找到dp数组中最大的值,即A[i]之前最大的值//2.若a[i]不满足a[i] > a[j]//则dp[i] = 1if (a[i] > a[j] && dp[j] > max)max = dp[j];}//最大值+1就是dp[i]dp[i] = max + 1;}dp2[N-1] = 1;for (i = N-2; i > 0; i--){int max = 0;for (j = N - 1; j > i; j--){//从右向左搜索dp数组,若满足上升序列的条件//1.若a[i] > a[j]//找到dp数组中最大的值,即A[i]之前最大的值//2.若a[i]不满足a[i] > a[j]//则dp[i] = 1if (a[i] > a[j] && dp2[j] > max)max = dp2[j];}//最大值+1就是dp2[i]dp2[i] = max + 1;}    for (i = 1; i < N; i++){if (dp[i]+dp2[i] > ans)ans = dp[i]+dp2[i] - 1;}return ans;}int main(int argc, char* argv[]){printf("%d\n", LIS(N-1));  //从左往右最长序列的长度return 0;}




0 0