zoukankan      html  css  js  c++  java
  • hihoCoder#1239 Fibonacci

    #1239 : Fibonacci

    时间限制:10000ms
    单点时限:1000ms
    内存限制:256MB

    描述

    Given a sequence {an}, how many non-empty sub-sequence of it is a prefix of fibonacci sequence.

    A sub-sequence is a sequence that can be derived from another sequence by deleting some elements without changing the order of the remaining elements.

    The fibonacci sequence is defined as below:

    F1 = 1, F2 = 1

    Fn = Fn-1 + Fn-2, n>=3  (微软2016年秋招第三题)

    输入

    One line with an integer n.

    Second line with n integers, indicating the sequence {an}.

    For 30% of the data, n<=10.

    For 60% of the data, n<=1000.

    For 100% of the data, n<=1000000, 0<=ai<=100000.

    输出

    One line with an integer, indicating the answer modulo 1,000,000,007.

    样例提示

    The 7 sub-sequences are:

    {a2}

    {a3}

    {a2, a3}

    {a2, a3, a4}

    {a2, a3, a5}

    {a2, a3, a4, a6}

    {a2, a3, a5, a6}

    样例输入

    6
    2 1 1 2 2 3

    样例输出

    7

    分析:

    题意就是找到给定序列中斐波那契子序列的个数。

    1. 首先想到的就是动态规划,dp[i]表示以i结尾的斐波那契子序列,然后每次变量j (0...i-1)更新i。

    但是这样时间复杂度是O(n^2),数据量10^6,肯定是超时的。

    2. 考虑优化,每次更新只与斐波那契数列中的元素结尾的有关,没必要dp开那么大,并且从头遍历。

    所以可以把dp存成vector<pair<int,int>>,一个表示值,一个表示以此结尾的fib序列个数。然后每次变量vector即可。

    但是很遗憾,还是超时了。。。(当数组中斐波那契数列中的数存在很多时,依然是个O(n^2))。

    3. 继续优化,其实每个遍历到每个数在斐波那契序列中,更新结果时,只与其在斐波那契序列中前一个数结尾fib序列个数有关。

    所以可以把dp[i]考虑存储为以fib[i]结尾的斐波那契子序列个数,100000以内斐波那契数只有25个,所以时间复杂度O(25n) = O(n),就可以了。

    注意: 用long long存result防止溢出;记得mod 1000000007

    代码:

     1 #include<iostream>
     2 #include<unordered_map>
     3 using namespace std;
     4 int fib[26];
     5 const int m = 1000000007;
     6 void init() {
     7     int a = 1, b = 1, c = 2;
     8     fib[1] = 1;
     9     fib[2] = 1;
    10     for (int i = 3; i <= 25; ++i) {
    11         c = a + b;
    12         fib[i] = c;
    13         a = b;
    14         b = c;
    15     }
    16 }
    17 int findPos(int x) {
    18     for (int i = 1; i <= 25; ++i) {
    19         if (fib[i] == x) {
    20             return i;
    21         }
    22     }
    23     return -1;
    24 }
    25 
    26 int n;
    27 int nums[1000000];
    28 long long dp[26] = {0};
    29 int main() {
    30     init();
    31     cin >> n;
    32     long long result = 0;
    33     for (int i = 0; i < n; ++i) {
    34         cin >> nums[i];
    35     }
    36     int first = -1, second = -1;
    37     for (int i = 0; i < n; ++i) {
    38         if (nums[i] == 1) {
    39             first = i;
    40             for (int j = i + 1; j < n; ++j) {
    41                 if (nums[j] == 1) {
    42                     second = j;
    43                     break;
    44                 }
    45             }
    46             break; 
    47         }
    48     }
    49     if (first != -1) {
    50         dp[1] = 1;
    51         result += 1;
    52     }
    53     if (second != -1) {
    54         dp[2] = 1;
    55         dp[1] ++;
    56         result += 2;
    57     }
    58     if (second == -1) {
    59         cout << result << endl;
    60         return 0;
    61     }
    62     
    63     for (int i = second + 1; i < n; ++i) {
    64         if (findPos(nums[i]) == -1 ) {
    65             continue;
    66         }
    67         if (nums[i] == 1) {  //1单独处理 
    68             dp[2] += dp[1];
    69             dp[1]++;
    70             result += dp[1];
    71             dp[2] %= m;
    72             result %= m;
    73             continue;
    74         }
    75         dp[findPos(nums[i])] += dp[findPos(nums[i]) - 1];
    76         result += dp[findPos(nums[i]) - 1];
    77         dp[findPos(nums[i])] %= m;
    78         result %= m;
    79     }
    80     cout << result << endl;
    81 }
  • 相关阅读:
    路由器基础配置之ospf基础配置
    路由器基础配置之广播多路访问链路上的ospf
    路由器基础设置之ospf
    linux命令之文件系统权限操作常用命令
    路由器基础配置之路由重分布
    路由器配置 之 DHCP+DHCP中继服务配置
    路由器配置 之 PAP与CHAP认证
    基于链路的OSPF MD5口令认证
    压缩和归档操作(16个命令)
    基于链路的OSPF简单口令认证
  • 原文地址:https://www.cnblogs.com/wangxiaobao/p/5862869.html
Copyright © 2011-2022 走看看