各种子序列问题

最长严格上升子序列

LIS问题,动归时间复杂度o(n2),可以用单调队列优化到o(nlogn)

http://blog.csdn.net/dangwenliang/article/details/5728363

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,dp[5005],orz[5005],ans = 0;
int main(){
    cin>>n;
    for(int i = 1;i <= n;i++) scanf("%d",&orz[i]);
    for(int i = 1;i <= n;i++){
        dp[i] = 1;
        for(int j = 1;j < i;j++){
            if(orz[i] > orz[j])dp[i] = max(dp[i],dp[j]+1);
            ans = max(ans,dp[i]);
        }
    }
    cout<<ans;
    return 0;
}
#include <iostream>
using namespace std;
int find(int *a,int len,int n)//修改后的二分查找,若返回值为x,则a[x]>=n
{
    int left=0,right=len,mid=(left+right)/2;
    while(left<=right)
    {
       if(n>a[mid]) left=mid+1;
       else if(n<a[mid]) right=mid-1;
       else return mid;
       mid=(left+right)/2;
    }
    return left;
}

int main(void)
{
    int n,a[100],c[100],i,j,len;//新开一变量len,用来储存每次循环结束后c中已经求出值的元素的最大下标
    while(cin>>n)
    {
        for(i=0;i<n;i++)
            cin>>a[i];
        b[0]=1;
        c[0]=-1;
        c[1]=a[0];
        len=1;//此时只有c[1]求出来,最长递增子序列的长度为1.
        for(i=1;i<n;i++)
        {
            j=find(c,len,a[i]);
            c[j]=a[i];
            if(j>len)//要更新len,另外补充一点:由二分查找可知j只可能比len大1
                len=j;//更新len
        }
        cout<<len<<endl;
    }
    return 0;
}

合唱队形

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>

using namespace std;
const int maxn = 200;
int dp[maxn],dps[maxn],value[maxn],n;

int main(){
    cin>>n;
    for(int i =1;i <= n;i++) cin>>value[i];
    dp[1] = dps[n] = 1;
    for(int i = 2;i <= n;i++){
        for(int j = 1;j < i;j++){
            if(dp[j] > dp[i] && value[i] > value[j]) dp[i] = dp[j];
        }
        dp[i]++;

    }
    for(int i = n-1;i >= 1;i--){
        for(int j = n;j > i;j--){
            if(dps[j] > dps[i] && value[i] > value[j]) dps[i] = dps[j];
        }
        dps[i]++;

    }
    int ans = 0;
    for(int i = 1;i <= n;i++) ans = max(ans,dp[i] + dps[i] - 1);
    cout<<n - ans;
    return 0;
}
时间: 2024-08-29 06:52:20

各种子序列问题的相关文章

14-高效求最长公共子序列(二维数组存不下)

/*                                   See LCS again时间限制:1000 ms  |  内存限制:65535 KB难度:3 描述 There are A, B two sequences, the number of elements in the sequence is n.m; Each element in the sequence are different and less than 100000. Calculate the length

POJ 2533 - Longest Ordered Subsequence(最长上升子序列) 题解

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置. 题目链接:http://poj.org/problem?id=2533 Description A numeric sequence of ai is ordered if a1 < a2 < ... < aN. Let the subsequence of the given numeric sequence (a1, a2, ..., aN) be any sequence (ai1, ai2, ..., aiK)

最大连续子序列和

对于给定的数组 numnum,一个长度为 ss 的连续子序列是指由 num_i,num_{i+1},num_{i+2}\ldots,num_{i+s-1}num?i??,num?i+1??,num?i+2??…,num?i+s−1?? 组成的序列.数组中的元素有可能为正数.负数或 00.你需要从数组中找出元素总和最大的一个连续子序列. 比如,对于数组 1,-3,2,6,-5,81,−3,2,6,−5,8,其最大连续子序列之和是 2+6-5+8=112+6−5+8=11. 对于一段区间内的最大连续

最长公共子序列的代码实现

关于最长公共子序列(LCS)的相关知识,http://blog.csdn.net/liufeng_king/article/details/8500084 这篇文章讲的比较好,在此暂时不再详说. 以下是我代码实现两种方式:递归+递推: 1 #include <bits/stdc++.h> 2 using namespace std; 3 int A[100]; 4 int B[100]; 5 6 //int B[]={2,3,5,6,9,8,4}; 7 int d[100][100]={0};

hdu1231 最大连续子序列

最大连续子序列 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 22849    Accepted Submission(s): 10135 Problem Description 给定K个整数的序列{ N1, N2, ..., NK },其任意连续子序列可表示为{ Ni, Ni+1, ..., Nj },其中 1 <= i <= j

计算数组的最大子序列之和

问题描述: 计算一个给定数组的最大子序列之和 分析: 有三种方法: 1,扫描3遍,可以计算所有的子序列之和,但是复杂度为N^3. 2,扫描2遍,计算以任意元素开始的和,如果大于当前的最大值则将最大值付给它,复杂度为N^2. 3,扫描一遍,计算任意元素开始的值,如果小于零则清零,否则继续往后加. 代码实现: package c02; /**  * @project: DataStructureAndAlgorithmAnalysis  * @filename: MaxSubSum  * @vers

HDU 3998 Sequence (最长递增子序列+最大流SAP,拆点法)经典

Sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1666    Accepted Submission(s): 614 Problem Description There is a sequence X (i.e. x[1], x[2], ..., x[n]). We define increasing subsequ

LintCode-乘积最大子序列

找出一个序列中乘积最大的连续子序列(至少包含一个数). 样例 比如, 序列 [2,3,-2,4] 中乘积最大的子序列为 [2,3] ,其乘积为6. 分析:访问到每个点的时候,以该点为子序列的末尾的乘积,要么是该点本身,要么是该点乘以以前一点为末尾的序列,注意乘积负负得正,故需要记录前面的最大最小值. 代码: class Solution { public: /** * @param nums: a vector of integers * @return: an integer */ int m

算法面试题 之 最长递增子序列 LIS

找出最长递增序列 O(NlogN)(不一定连续!) 参考 http://www.felix021.com/blog/read.php?1587%E5%8F%AF%E6%98%AF%E8%BF%9E%E6%95%B0%E7%BB%84%E9%83%BD%E6%B2%A1%E7%BB%99%E5%87%BA%E6%9D%A5 我就是理解了一下他的分析 用更通俗易懂的话来说说题目是这样 d[1..9] = 2 1 5 3 6 4 8 9 7 要求找到最长的递增子序列首先用一个数组b[] 依次的将d里面

NYOJ 36 &amp;&amp;HDU 1159 最长公共子序列(经典)

链接:click here 题意:tip:最长公共子序列也称作最长公共子串(不要求连续),英文缩写为LCS(Longest Common Subsequence).其定义是,一个序列 S ,如果分别是两个或多个已知序列的子序列,且是所有符合此条件序列中最长的,则 S 称为已知序列的最长公共子序列. 输入 第一行给出一个整数N(0<N<100)表示待测数据组数 接下来每组数据两行,分别为待测的两组字符串.每个字符串长度不大于1000. 输出 每组测试数据输出一个整数,表示最长公共子序列长度.每组