被这个问题困住了,就像憋了一泡屎,但是便秘了,不往下说了,你懂的。
在网上查了各种资料,各种文章,其实大家说的都差不多,无非是枚举、求该序列和它的排序后的序列的最大公共子序列、动态规划、基于〈二分法和统计研究〉论文。最基本最正常路子应该是动态规划,很多人会给出一个公式,然后给出一段代码,我看了很多,最终只看懂了一个。描述如下:
比如:另d[i]表示数列1到i, 以i结尾的最大长度值, 而令d[i] = max{ d[j]+1} (1<=j<=i-1 && a[j] > a[i])也就是说,对于每个可以接上的值, 都有a[j] > a[i](递减), 看谁能接的长, 自然就是最优解了。如果没有可接的, 就说明对于a[i]前边的没一个值, 都有a[j]>a[i], 也就是说a[i]是迄今位置最大的数了, 那么有d[i] = 1;
单看这个,想写出程序来也很难,所以,最好还是直接看程序。
对于poj上的1952题,难点其实是在计数上,m[i]用来存放计数,何时初始化计数?计数如何增加?如何防止重复?这是几个要考虑的问题,答案都在代码中了。
输入用例:
12 68 69 54 64 68 64 70 67 78 62 98 87
输出用例:
4 2 //最长是4;有2个长度为4的子序列
源程序:
1 #include2 int array[5000+1]; 3 int d[5000+1]; 4 int m[5000+1]; 5 int lds(int n) 6 { 7 int max; 8 int i, j; 9 for(i=n-1; i>=0; --i)10 {11 for(j=i+1; j array[j])14 {15 if(d[i] < d[j]+1)16 {17 d[i] = d[j]+1;18 m[i] = m[j];19 }20 else if(d[i] == d[j]+1)21 {22 m[i] += m[j];23 }24 }25 else if(array[i] == array[j])26 {27 if(d[i] == 1)28 {29 m[i] = 0;30 }31 break;//防止重复32 }33 }34 }35 for(i=0, max=0; i