应该算是比较经典的一道题目了。 无论是按字母顺序或者按数字顺序,解题的思路都应该是一样的。 用动态规划,划分为子问题,就是每个元素当前位置之前的最长子序列加上它自身这个值,就是当前的最长子序列长度。 总结一下,算法核心思想就是要找到当前位置元素之前的每个元素对应的最长下降/上升子序列的最大值,然后将它加一,就等于当前位置的子序列长度值了。其复杂度为$latex O(n^{2})$. 详见下代码。
以最长下降子序列为例:
#include"stdio.h" #include"string.h" int main(void) { int n; scanf("%d",&n); while(n--) { int m,i,j,max,maxlen; //max用于记录当前位置之前的子序列最大值,maxlen用于记录整个串的最长子序列最值 scanf("%d",&m); int height[m]; int sum[m]; maxlen=1; for(i=0;i<m;i++) { scanf("%d",&height[i]); sum[i]=1; max=0; for(j=i-1;j>=0;j--) { if(height[j] > height[i] && sum[j]>max) max=sum[j]; } sum[i]+=max; if(sum[i]>maxlen) maxlen=sum[i]; } printf("%d\n",maxlen); } return 0; }
查看原文:http://www.wyblog.cn/2016/10/10/%e5%8a%a8%e6%80%81%e8%a7%84%e5%88%92-%e6%b1%82%e6%9c%80%e9%95%bf%e4%b8%8b%e9%99%8d%e4%b8%8a%e5%8d%87%e5%ad%90%e5%ba%8f%e5%88%97-2/
动态规划——求最长下降/上升子序列
最新推荐文章于 2024-05-11 22:02:29 发布