POJ 1631 Bridging Singnals

110MS, O(nlog(n))的算法,怎样才能更快?那些10几个MS的是怎样实现的?

  1  Source Code
  2  Problem:  1631         User: goldenlock
  3  Memory: 628K        Time: 110MS
  4  Language: G ++         Result: Accepted
  5 
  6       *  Source Code
  7 
  8         /*
  9         *  ==============================================================================
 10         * 
 11         *          \file   bridging_signals_1631.cc
 12         *
 13         *        \author   pku_goldenlock@qq.com
 14         *
 15         *          \date   2009-10-28 21:41:57.539397
 16         *  
 17         *   Description:   pku 1631,
 18         *                  本质上就是求最长只增序列,编程之美上
 19         *                  有解释.下面只要提到序列就是递增序列.
 20         *                  疑问,两个左边的指向同一个右边的算相交了吗?假定不算相交
 21         *                  不算的话就允许递增序列有相同大小的元素,如果算就不能有.
 22         *                  不管算不算相交,都是求upper_bound,如果不算的化,元素全
 23         *                  不相同.恩,本题目是没有相同元素的,不会左边两个连右边
 24         *                  同一个的.但是解法并不改变.
 25         *                  思路:
 26         *                  依次求以第n个元素结尾的只增序列长度l[n],记录所有的l[]最大的一个即
 27         *                  为所求.
 28         *                  核心优化:
 29         *                  最本质的规律是前面的l[k],l[j]相等的化, 假如data[k] < data[j]
 30         *                  那么后面元素就不需要去考虑data[j]!在同等长度下,尾元素小的序
 31         *                  列优先.
 32         *                  
 33         *                  因此可以记录各个长度的序列,记录其对应的最小尾元素.
 34         *                  考虑长度为i(1,2,3,4.)这样的递增长度序列,其对应的最小尾元素t[i]也
 35         *                  是递增的.否则假如如果i > j 而t[i] < t[j] 则存在 x < t[i] < t[j]
 36         *                  l[x] = t[j]  与t[j] 是长度为j的序列的最小尾元素矛盾.
 37         *
 38         *                  因为递增长度对应的最小尾元素也递增,所以可以二分查找.
 39         *                  对于扫描到第n个元素, data[n],去最小尾元素序列二分查找
 40         *                  data[n](stl upper_bound),返回第一个比data[n]大的位置k,令t[k] = data[n],
 41         *                  即更新长度位k的序列的最小尾元素值.
 42         *                  最后返回最长的那个序列的长度即可.
 43         *
 44         *  ==============================================================================
 45          */
 46        #include  < stdio.h >
 47         /*   
 48         * for spped, your response to let end >= 0
 49         * 对这个特殊的问题,没有相同元素,所以一定查找不到key
 50         * 如1 2 4 查找3 返回index 2  t[2] = 4(upper_bound!)
 51         * upper_bound和lower_bound的区别在于 upper_bound return start, lower_bound return end.
 52         * search 1.5
 53         *        1
 54         *        end start
 55         * search     0.5
 56         *            1
 57         *        end start
 58         * 最后总是start指向比key大的第一个数字位置,end指向比key小的第一个位置
 59         * the last status : end key start
 60         * TODO try std::upper_bound, the same:)
 61          */
 62        inline  int  upper_bound( int  t[],  int  end,  int  key) {
 63           int  start  =   0 ;
 64           int  mid;
 65           while  (start  <=  end) {
 66            mid  =  (start  +  end) / 2 ;
 67             // 考虑假设有相同元素的情况(本题目没有),必须这么写,不能key <= t[mid],i
 68             // lower_bound 要写 if key > t[mid] start = mid + 1
 69             if  (key  <  t[mid])  
 70              end  =  mid  -   1 ;
 71             else
 72              start  =  mid  +   1 ;
 73          }
 74           return  start;
 75        }
 76 
 77        inline  int  maxIncreasingSequence( int  data[],  int  len) 
 78        {
 79           // --------------------init
 80           int  max_len  =   0 ;
 81           int  t[len];
 82          t[ 0 =  data[ 0 ];  
 83           int  pos;
 84           // --------------------find max length
 85           for  ( int  i  =   1 ; i  <  len; i ++ ) {
 86            pos  =  upper_bound(t, max_len, data[i]);
 87             if  (pos  >  max_len)   // get longer sequence
 88              max_len  =  pos;
 89             // modify(or add) the smallest ending value 
 90             // for sequence with length as pos + 1
 91            t[pos]  =  data[i];    
 92          }
 93           // --------------------return
 94           return  max_len  +   1 ;   // due to staring index is 1 not 0
 95        }
 96 
 97         int  main( int  argc,  char   * argv[])
 98        {
 99           int  test_num;
100          scanf( " %d " & test_num);
101           int  array_length;
102           // -----------------run each test case
103           for  ( int  i  =   0 ; i  <  test_num; i ++ ) {
104             // ------------------------get input
105            scanf( " %d " & array_length);
106             int  data[array_length];
107             for  ( int  j  =   0 ; j  <  array_length; j ++ ) {
108              scanf( " %d " & data[j]); 
109            }
110             // ------------------------print result
111            printf( " %d\n " , maxIncreasingSequence(data, array_length));
112          }
113           return   0 ;
114        }
115 
116 

 

可以复用data数组,即不需要t数组,不过不改善什么性能.

 1  #include  < stdio.h >
 2 
 3  inline  int  upper_bound( int  data[],  int  end,  int  key) {
 4     int  start  =   0 ;
 5     int  mid;
 6     while  (start  <=  end) {
 7      mid  =  (start  +  end) / 2 ;
 8       // 考虑假设有相同元素的情况(本题目没有),必须这么写,不能key <= t[mid],i
 9       // lower_bound 要写 if key > t[mid] start = mid + 1
10       if  (key  <  data[mid])  
11        end  =  mid  -   1 ;
12       else
13        start  =  mid  +   1 ;
14    }
15     return  start;
16  }
17 
18  inline  int  maxIncreasingSequence( int  data[],  int  len) 
19  {
20     // --------------------init
21     int  max_len  =   0 ;
22     int  pos;
23     // --------------------find max length
24     for  ( int  i  =   1 ; i  <  len; i ++ ) {
25      pos  =  upper_bound(data, max_len, data[i]);
26       if  (pos  >  max_len)      // get longer sequence
27        max_len  =  pos;
28      data[pos]  =  data[i];     // modify smallest tail value
29     }
30     // --------------------return
31     return  max_len  +   1 ;   // due to staring index is 1 not 0
32  }
33 
34  int  main( int  argc,  char   * argv[])
35  {
36     int  test_num;
37    scanf( " %d " & test_num);
38     int  array_length;
39     // -----------------run each test case
40     for  ( int  i  =   0 ; i  <  test_num; i ++ ) {
41       // ------------------------get input
42      scanf( " %d " & array_length);
43       int  data[array_length];
44       for  ( int  j  =   0 ; j  <  array_length; j ++ ) {
45        scanf( " %d " & data[j]); 
46      }
47       // ------------------------print result
48      printf( " %d\n " , maxIncreasingSequence(data, array_length));
49    }
50     return   0 ;
51  }
52 
53 

 

 

深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值