子序列相关有关问题

子序列相关问题

1.最长连续递增(减)子序列的长度


样例输入:

7

1 7 4 6 9 2 10 

样例输出:

3


#include<iostream>
#include<cstdio>
using namespace std;
int dp[10010],a[10101];
int main()
{
    //freopen("input.txt","r",stdin);
    int i,j;
    int m,n;
    int maxn;
    while(cin>>m)
    {
        maxn=0;
        for(i=1;i<=m;i++)
        {
            cin>>a[i];
            dp[i]=1;
        }
        for(i=1;i<=m;i++)
        {
            if(a[i]>a[i-1])
                    dp[i]=dp[i-1]+1;

            maxn=max(maxn,dp[i]);

        }
        cout<<maxn<<endl;
    }
    return 0;
}


2.最长不连续递增(减)子序列的长度


样例输入:

7

1 7 4 6 9 2 10 

样例输出:

5


#include<stdio.h>  
int main ()  
{  
  int n,i,j;   
  int a[1006],dp[1006];  
  scanf("%d",&n);  
  for(i=0;i<n;i++)  
  {  
   scanf("%d",&a[i]);  
      dp[i]=1;  // 初始化
  }  
  
  for(i=0;i<n;i++)  
  {  
    for(j=0;j<i;j++)  
    {  
      if(a[i]>a[j] && dp[i]<dp[j]+1)  //  a[j]和a[i]能构成一个上升子序列,然后把当前上升子序列的长度存到dp[i]中  
          dp[i]=dp[j]+1;  
    }  
  }  
  int t=0;
  for(i=0;i<n;i++)  
  {  
    if(dp[i]>t)  
        t=dp[i];  
  }  
  printf("%d\n",t);  
  return 0;  
}  



3.最长不连续递增(减)子序列的和


样例输入:

7

14 6 9 2 10 

样例输出:

30


#include<stdio.h>  
#include<algorithm>  
#include<iostream>  
using namespace std;  
int a[1005],dp[1005];  // dp[]数组 表示子序列和  
int main()  
{  
    int n;  
    int i,j;   
    while((cin>>n)&&n)  
    {  
        for(i=0;i<n;i++)  
        {  
            cin>>a[i];  
            dp[i]=a[i];  // 初始化
        }  
  
        for(i=0;i<n;i++)  
            for(j=0;j<i;j++)  
            {  
              if(a[i]>a[j] && dp[i]<dp[j]+a[i])  
                        // a[j]和a[i]能构成一个上升子序列,然后把当前上升子序列的和存到dp[i]中  
                  dp[i]=dp[j]+a[i];  
            }  
  
        int max=dp[0];  
        for(i=1;i<n;i++)  
            if(dp[i]>max)  
               max=dp[i];  // 求出最大值  
        cout<<max<<endl;  
        }  
        return 0;  
}  


4.最长公共子序列


for(i=1;i<=n;i++)    // 求最长公共子序列  
{  
    for(j=1;j<=n;j++)  
    {  
        if(a[i]==b[j]) dp[i][j]=dp[i-1][j-1]+1;  
        else           dp[i][j]=max(dp[i-1][j],dp[i][j-1]);  
    }  
      
}  


5.不连续递增(减)子序列的个数


样例输入:

7

1 4 9 2 10 

样例输出:

2


#include<stdio.h>  
int main ()  
{  
    int n,a[1000],b[1000],i,j,t;  
    while (~scanf("%d",&n))  
    {      
        for(i=0;i<n;i++)  
        {  
            scanf("%d",&a[i]);  
            b[i]=0;      // 标记
        }  
        int num=0;  
        for(i=0;i<n;i++)  
        {  
            if(b[i]==0)  
            {     
                b[i]=1;  // 访问过
                t=a[i];  
                for(j=i+1;j<n;j++)  
                {  
                    if((b[j]==0)&&(t<=a[j]))  
                    {  
                        t=a[j];  
                        b[j]=1;  
                    }  
                }  
                num++;  
            }  
              
        }  
          
        printf("%d\n",num);  
    }  
    return 0;  
}  


6.最大连续子序列


样例输入:

6

3 -4 2 3 -1 8

样例输出:

12


#include<stdio.h>  
int main()  
{  
    int i,n,sum,max,flag,start,end,temp;    //start、end记录最大连续子序列的开始位置和结束位置  
    int a[10001];  
    while(scanf("%d",&n) && n!=0)  
    {  
        flag=0;                    //判断当输入全为负数时,令flag=0,否则flag=1  
        for(i=0;i<n;i++)  
        {  
            scanf("%d",&a[i]);  
            if(a[i]>=0)  
                flag=1;  
        }  
  
        if(flag==0)                 //当全为负数时输出max=0  
        {  
            printf("0 %d %d\n",a[0],a[n-1]);  
            continue;  
        }  
  
        else  
        {     
            max=sum=a[0];  
            temp=start=end=0;  
            for(i=1;i<n;i++)       
            {  
                if(sum<0)         //  一旦sum<0,令sum归零.   
                {  
                    temp=i;       //   记下 使sum<0 是第几项.(i)  
                    sum=0;  
                }  
  
                sum+=a[i];  
                if(sum>max)        //  sum增加,变换start及end的值  
                {  
                    max=sum;  
                    start=temp;  
                    end=i;     
                }  
            }  
            printf("%d %d %d\n",max,a[start],a[end]);  
        }  
    }  
    return 0;  


#include<iostream>
#include<cstdio>
using namespace std;
int dp[101],a[101];
int main(int i,int j)
{
    int m,n;
    int maxn;
    while(cin>>m)
    {
        maxn=-999;
        for(i=0;i<m;i++)
        {
            cin>>a[i];
            dp[i]=a[i];
        }
        for(i=0;i<m;i++)
        {
            for(j=0;j<i;j++)
            //if(a[i]>a[i-1])
                dp[i]=max(dp[j]+a[i],a[i]);
           maxn=max(maxn,dp[i]);
        }
        cout<<maxn<<endl;
    }
    return 0;
}


7.最大递增(减)连续子序列


样例输入:

9

1 5 2 4 6 91 10 12

样例输出:

23


#include<iostream>
#include<cstdio>
using namespace std;
int dp[101],a[101];
int main(int i,int j)
{
    int m,n;
    int maxn;
    while(cin>>m)
    {
        maxn=-999;
        for(i=0;i<m;i++)
        {
            cin>>a[i];
            dp[i]=a[i];
        }
        for(i=1;i<m;i++)
        {
            if(a[i]>a[i-1])
                dp[i]=max(dp[i-1]+a[i],a[i]);
            maxn=max(maxn,dp[i]);
        }
        cout<<maxn<<endl;
    }
    return 0;
}