C语言算法讲解辅导、辅导C语言算法单调递增子序列

- 首页 >> C/C++编程

题目如下:


设计一个O(n2)时间的算法,找出由n个数组成的序列的最长单调递增子序列。


解题思路:


思路一:简单dp,求最长递增子序列,即为求其与已经排好序的序列的公共子序列


/*设计一个O(n2)时间的算法,找出由n个数组成的序列的最长单调递增子序列。*/

#include <iostream>

#include<vector>

#include<algorithm>

using namespace std;

#define N 100


void fun(int n);


vector< int > a,b;


void main()

{

int i,n,temp;

printf("input n:");

scanf("%d",&n);

printf("input the array.\n");

for(i=0;i<n&&cin>>temp;i++)

a.push_back(temp);

b=a;

sort(b.begin(),b.end());

fun(n);


}


void fun(int n)

{

int m[N][N],flag[N];

if(a[0]!=b[0])

m[0][0]=0;

else

m[0][0]=1;

for(int i=0;i<n;i++)

{

for(int j=0;j<n;j++)

{

if(i==0&&j==0)

{

continue;

}

if(a[i]==b[j])

{

if(i==0)

m[i][j]=m[0][j-1]+1;

else if(j==0)

m[i][j]=m[i-1][0]+1;

else

   m[i][j]=m[i-1][j-1]+1;

}

else

{

if(i==0)

m[i][j]=m[i][j-1];

else if(j==0)

m[i][j]=m[i-1][j];

else

m[i][j]=(m[i-1][j]>m[i][j-1]?m[i-1][j]:m[i][j-1]);

}

}

}

for(int k=n-1;k>=0;k--)

{

if(k==0&&m[0][0]!=0)

flag[k]=1;

else if(m[k][k]>m[k-1][k-1])

flag[k]=1;

else

flag[k]=0;

}

cout<<"len="<<m[n-1][n-1]<<endl;

cout<<"the number are:";

for(int h=0;h<n;h++)

{

if(flag[h])

{

cout<<a[h]<<" ";

}

}

cout<<endl;

}



第二种思路

/*设计一个O(n2)时间的算法,找出由n个数组成的序列的最长单调递增子序列。*/

#include <stdio.h>

#define N 100


void prin(int i);

void fun(int n);

int p[N],a[N];


void main()

{

int i,n;

printf("input n:");

scanf("%d",&n);

printf("input the array.\n");

for(i=0;i<n;i++)

scanf("%d",&a[i]);

fun(n);


}


void fun(int n)

{

int m[N];

int i,k,max;

m[0]=1;

p[0]=-1;

for(i=1;i<n;i++)

{

max=0;

p[i]=-1;

for(k=0;k<i;k++)

{

if(m[k]>max&&a[k]<a[i])

{

p[i]=k;

max=m[k];                  

}

}

m[i]=max+1;

}

i=0;

for(k=1;k<n;k++)

{

if(m[k]>m[i])

{

i=k;

}

}

prin(i);

printf("\nlen=%d\n",m[i]);


}


void prin(int i)

{

if(p[i]<0)

{

printf("%d",a[i]);

return;

}

prin(p[i]);

printf(",%d",a[i]);

}


站长地图