各种子序列问题

Posted ACforever

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了各种子序列问题相关的知识,希望对你有一定的参考价值。

最长严格上升子序列

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;
}

 

以上是关于各种子序列问题的主要内容,如果未能解决你的问题,请参考以下文章

两个不同的种子产生相同的“随机”序列

在具有相同种子的不同操作系统上实现相同的随机数序列

C# - 从序列中获取种子

关于在各浏览器中插入音频文件的html代码片段

用于自动打印的功能。各种子图和各种图形

Android 事件分发事件分发源码分析 ( Activity 中各层级的事件传递 | Activity -> PhoneWindow -> DecorView -> ViewGroup )(代码片段