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++

ExpandedBlockStart.gif 代码
 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  }


转载于:https://www.cnblogs.com/vivyli/archive/2010/02/05/1664063.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值