斐波那契数组

斐波那契数组

1.题目描述

如果数组 A = ( a 0 , a 1 , ⋯ . a n − 1 ) A=(a_0,a_1,⋯.a_{n-1})A=(a0,a1 ,⋯.a n−1 )满足以下条件, 就说它是一个斐波那契数组:n ≥ 2 ; n≥2;n≥2;a 0 = a 1 a_0=a_1a 0=a1对于所有的 i ( i ≥ 2 ) , i(i≥2),i(i≥2),都满足 a i = a i − 1 + a i − 2 。 a_i=a_{i-1}+a_{i-2}。ai=ai−1+ai−2 。

现在, 给出一个数组 A AA, 你可以执行任意次修改, 每次修改将数组中的某 个位置的元素修改为一个大于 0 的整数。请问最少修改几个元素之后, 数组 A AA 会变成一个斐波那契数组。

2.输入格式

输入的第一行包含一个整数 n nn,表示数组 A AA 中的元素个数。

第二行包含 n nn 个整数 a 0 , a 1 , ⋯ . a n − 1 , a_0,a_1,⋯.a_{n-1},a0 ,a1,⋯.a n−1 ,相邻两个整数之间用一个空格分隔。

3.输出格式

输出一行包含一个整数表示最少需要修改数组 A AA 中的几个元素之后, 数组 A AA 可以变为一个斐波那契数组。

4.样例输入

5

1 2 2 4 8

5.样例输出

3

6.数据范围

2 ≤ n ≤ 1 0 5 , 1 ≤ a i ≤ 1 0 6 。 2≤n≤10^5,1≤a_i≤10^6。2≤n≤105,1≤ai≤106 。

2.解题思路

首先考虑斐波那契数组具有什么性质,我们令 a 0 = a 1 = 1 a_0=a_1=1a0=a1=1去打印出前30位斐波那契数.不难发现,在不到30位的情况下,斐波那契数组的值已经超出了1e6,而注意到题目给定的aia_iai的最大值才为 1e6。这说明其实后面的数我们根本无需考虑,都是必须要修改的。

接下来我们就只需要考虑前30位数最多可以保留多少个数,假设最多可以保留x个数,那么答案就为n-x。对于斐波那契数列,如果 a 0 a_0a 0确定了,那么整个数列都确定了。所以我们可以枚举 a 0 a_0a

0的值,枚举的范围为[ 1 , 1 0 6 ] 。 [1,10^6]。[1,10 6]。然后去计算出前三十位的值,看与原数组符合预期的数有多少个,所有符合预期的数量取一个最大值x,最终答案即为n-x。时间复杂度O ( 30 ∗ 1 0 6 ) O(30*10^6)O(30∗10 6)

import java.io.*;
import java.util.Scanner;
public class Main {
static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
static int[] arr = new int[50];
static int V = 1000000;
public static void main(String[] args) throws IOException {
Scanner sc = new Scanner(System.in);
//表示无穷大
int res = 0x3f3f3f3f;
int n = sc.nextInt();
int count = n;
//我只读入前三十个数
if (n > 30) n = 30;
for (int i = 1; i <= n; i++) {
arr[i] = sc.nextInt();
}
//枚举开头是多少 30*1e6 3e7
for (int i = 1; i <= V; ++i) {
int a = i, b = i, c = 0;
int ans = 0;
if (arr[1] == a) ans++;
if (arr[2] == b) ans++;
for (int j = 3; j <= 30; ++j) {
c = a + b;
//这里是一个减枝
if (c > V) break;
if (c == arr[j]) ans++;
a = b;
b = c;
}
res = Math.min(count - ans, res);
}
out.println(res);
out.flush();
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值