您的位置:首页 > 其它

第十五章动态规划之“O(n^2)时间寻找n个数构成序列的最长递增子序列”(练习15.4-5)

2012-05-04 22:16 351 查看
这个问题类似于两个序列的最长公共子序列问题,但是这里只有一个序列啊?肿么办?想想这个n个数的序列,要想找它最长递增子序列,这个子序列肯定是从小到大排序的,从小到大排序的耶!跟谁对应呢?思路来了!先把原序列从小到大排序,然后跟原序列对比寻找最长公共子序列!排序时间为O(nlgn),两个长度为n的序列寻找最长子序列为O(n^2),所以总的时间复杂度为O(n^2)。

代码:

#include <iostream>
using namespace std;

int RandomPartition(int *b,int p,int r)
{
srand((unsigned int)time(NULL));
int x=rand()%(r-p+1);
x=p+x;

int temp=b[x];
b[x]=b[r];
b[r]=temp;

int i=p-1;
int key=b[r];
for(int j=p;j<r;j++)
{
if(b[j]<key)
{
i++;
int temp=b[i];
b[i]=b[j];
b[j]=temp;
}
}
i++;
int tmp=b[i];
b[i]=b[r];
b[r]=tmp;

return i;
}

void QuickSort(int *b,int p,int r)
{
if(p>=r)
{
return;
}
int q=RandomPartition(b,p,r);
QuickSort(b,p,q-1);
QuickSort(b,q+1,r);
}

void LCSLength(int *a,int *b,int m,int n,int (*c)[11],int (*bb)[11])
{
for(int i=0;i<=m;i++)
{
c[i][0]=0;
}
for(int i=0;i<=n;i++)
{
c[0][i]=0;
}

for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++)
{
if(a[i]==b[j])
{
c[i][j]=c[i-1][j-1]+1;
bb[i][j]=0;
}
else
{
if(c[i][j-1]>c[i-1][j])
{
c[i][j]=c[i][j-1];
bb[i][j]=1;
}
else
{
c[i][j]=c[i-1][j];
bb[i][j]=2;
}
}
}
}
}

void PrintLCS(int *a,int (*bb)[11],int i,int j)
{
if(i==0||j==0)
{
return;
}
if(bb[i][j]==0)
{
PrintLCS(a,bb,i-1,j-1);
cout<<a[i]<<" ";
}
else if(bb[i][j]==1)
{
PrintLCS(a,bb,i,j-1);
}
else
{
PrintLCS(a,bb,i-1,j);
}
}

int main()
{
srand((unsigned int)time(NULL));
int a[10];
int b[10];
int n=10;
for(int i=0;i<n;i++)
{
a[i]=rand()%1000;
}
for(int i=0;i<n;i++)
{
b[i]=a[i];
}
QuickSort(b,0,n-1);

cout<<"a[]:";
for(int i=0;i<n;i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
cout<<"b[]:";
for(int i=0;i<n;i++)
{
cout<<b[i]<<" ";
}
cout<<endl;
int c[11][11];
int bb[11][11];
LCSLength(a,b,n,n,c,bb);
cout<<"Length="<<c

<<endl;
PrintLCS(a,bb,n,n);

system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: