最长单调子序列及计数(poj1952)

  被这个问题困住了,就像憋了一泡屎,但是便秘了,不往下说了,你懂的。

  在网上查了各种资料,各种文章,其实大家说的都差不多,无非是枚举、求该序列和它的排序后的序列的最大公共子序列、动态规划、基于〈二分法和统计研究〉论文。最基本最正常路子应该是动态规划,很多人会给出一个公式,然后给出一段代码,我看了很多,最终只看懂了一个。描述如下:

  比如:另d[i]表示数列1i 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 #include <stdio.h>
 2 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<n; ++j)
12         {
13             if(array[i] > 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<n; ++i)
36     {
37         if(max < d[i])
38         {
39             max = d[i];
40         }
41     }
42     int maxm;
43     for(i=0, maxm=0; i<n; ++i)
44     {
45         if(d[i] == max)
46         {
47             maxm += m[i];
48         }
49     }
50     printf("%d %d\n", max, maxm);
51     return 0;
52 }
53 int main()
54 {
55     int i=0;
56     int nLastNum = -1;
57     int nArrayLen;
58     scanf("%d", &nArrayLen);
59     i=0;
60     while(i < nArrayLen)
61     {
62         scanf("%d", &array[i]);
63         m[i] = 1;
64         d[i] = 1;
65         ++i;
66     }
67     while(i<5001)
68     {
69         m[i] = 1;
70         d[i] = 1;
71         ++i;
72     }
73     lds(nArrayLen);
74     return 0;
75 }

 

 

posted on 2012-08-28 14:32  favourmeng  阅读(1082)  评论(0编辑  收藏  举报

导航