ZOJ 2527题解

    题目链接

    题目的大概意思是给出一个序列,这个序列的数字都是整数,范围是-1,000,000,000 到1,000,000,000,数字的数量在2到1000,要求求出这个序列最长的等差子序列的长度。

    我的想法,最长的相等的子序列作为maxlen的初始值,因为这个就是一个等差的子序列,然后把相同数字合并变为一个,这样可以减小数据量。

    然后用排序一下,再用O(N*N*N)的复杂度求解,当然,这个可以做一些优化,当求最长等差子序列的时候,方法是先选定两个数字,得到这两个数字的差, 然后不断的求下一个数,通过map找这个数字,找到一个len加1,如果没找到直接跳出。

    在这个地方我想应该还可以做一个优化,如果这两个数字已经被前面的等差序列找过的话就不用找了,比如2,3,4,5,当找2,3的时候,同时找过4,5 了,当找4,5的时候发现前面已经同时找过就不用再找下去了;另外,如果较大的一个数字后面的数字的个数已经小于maxlen了,就不用找了,但是这个优 化的效果不是很明显,于是就不做了。

    我的代码速度比较慢,没有dp,其实就是死做的,0.46s通过,看看最快的是0.02s,还有很大的差距啊,附上代码:in C++

代码
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<map>
 4 #include<vector>
 5 #include<cstdlib>
 6 using namespace std;
 7 
 8 int cmp(const void *a, const void *b)
 9 {
10 int *t1, *t2;
11 t1 = (int *)a;
12 t2 = (int *)b;
13 return (*t1) - (*t2) ;
14 }
15 int main()
16 {
17 map<int ,int> m;
18 int num[1000];
19 int n;
20 
21 while(scanf("%d",&n) != EOF)
22 {
23    int t = 0;
24    int maxlen = 0 ;
25    for(int i = 0 ; i < n ; i ++)
26    {
27     int temp;
28     scanf("%d",&temp);
29     if(!m[temp])
30      num[t++= temp;
31     m[temp] ++ ;
32     if(maxlen < m[temp])
33      maxlen = m[temp] ;
34    }
35    qsort(num,t,sizeof(int),cmp);
36    for(int i = 0 ; i < t ; i ++)
37     for(int j = i + 1 ; j < t ; j ++)
38     {
39      int cur = num[j];
40      int len = 1 ;
41      int co = num[j] - num[i];
42      while(m[cur])
43      {
44       len ++ ;
45       cur += co ;
46      }
47      if(len > maxlen)
48       maxlen = len ;
49     }
50    printf("%d\n",maxlen);
51   
52 }
53 
54 return 0;
55 }


posted on 2010-02-05 01:46  vivy  阅读(347)  评论(0)    收藏  举报