单调连续递增子序列(O(n2)

来源:互联网 发布:要成为一个编程大牛 编辑:程序博客网 时间:2024/06/06 06:29

2016,4,2   16:03 

题目:

单调递增最长子序列

时间限制:3000 ms  |  内存限制:65535 KB
难度:4
描述
求一个字符串的最长递增子序列的长度
如:dabdbf最长递增子序列就是abdf,长度为4
输入
第一行一个整数0<n<20,表示有n个字符串要处理
随后的n行,每行有一个字符串,该字符串的长度不会超过10000
输出
输出字符串的最长递增子序列的长度
样例输入
3aaaababcabklmncdefg
样例输出
137

思想:这道题时间复杂度为o(n2),是LCS(最长公共子序列)的变形。相当于 一个x  原数组,一个y  数组由x  数组 升序排列并去掉重复值,求两个数组的最长公共子序列问题。

  代码:

<pre name="code" class="cpp"><span style="font-size:18px;">//注意:二维数组的传递 方式 #include <stdio.h>#include <string.h>char x[10001];char y[10001];int c[27][10001];int  AscendingLCS(int m,int n ){int i,j;//初始化 for(i=0;i<m;i++)*((int *)c+i*n+0)=0;for(j=0;j<n;j++)*((int *)c+0+j)=0;//dp: o(n^2) for(i=1;i<m;i++){for(j=1;j<n;j++){if(x[i-1]==y[j-1]){*((int *)c+i*n+j)=*((int *)c+(i-1)*n+j-1)+1;}else {if(*((int *)c+(i-1)*n+j)>=*((int *)c+i*n+j-1)){*((int *)c+i*n+j)=*((int *)c+(i-1)*n+j);}else{*((int *)c+i*n+j)=*((int *)c+i*n+j-1);}}} }//返回最优值 (最优值是手工转变为:  *((int*)array + n*i + j);) return *((int *)c+(m-1)*n+n-1); }int main(void){int i,j,min,L=0,k,S;//S行,L列 int m;scanf("%d",&m);getchar();while(m--){scanf("%s",x);L=strlen(x);S=L;//复制到 y 数组strcpy(y,x);//数组排序并去掉重复值                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               for(i=0;i<L-1;i++){min=i;for(j=i+1;j<L;j++){if(y[j]<y[min]){min=j;}}if(min!=i){int temp=y[min];y[min]=y[i];y[i]=temp;}}//排好序去重复值 i=0;while(i<L-1){if(y[i+1]==y[i]){for(k=i;k<L-1;k++){y[k]=y[k+1];}L--;}else i++;}printf("%d\n", AscendingLCS(S+1,L+1));}return 0;} </span>



做题心得

1.二维数组的传递方式:

对于下面的声明:

int hoge[2][3;]

方式一:void func(int **hoge):则数组元素需经手工运算:*((int*)c + n*i + j);) .

方式二:void func(int (*hoge) [3]),

或是:

void func(int hoge[][3]);

或是:

void func(int hoge[2][3];


1 0
原创粉丝点击