首页 > 其他分享 >蓝桥杯2022年第十三届决赛真题-斐波那契数组(动态规划)

蓝桥杯2022年第十三届决赛真题-斐波那契数组(动态规划)

时间:2023-05-23 23:34:29浏览次数:48  
标签:斐波 数列 真题 int 蓝桥 数组 那契 dp

题目描述

如果数组 A = (a0, a1, · · · , an−1) 满足以下条件,就说它是一个斐波那契数组:

  1. n ≥ 2;

  2. a0 = a1;

  3. 对于所有的 i(i ≥ 2),都满足 ai = ai−1 + ai−2。

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

输入格式

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

第二行包含 n 个整数 a0, a1, · · · , an−1,相邻两个整数之间用一个空格分隔。

输出格式

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

样例输入

3
4 6 9

样例输出

4

解答

  1. 这道题是典型的斐波那契数列题,而且因为题目的数据范围很大,使用暴力递归几乎全部数据都会超时,所以我们使用动态规划进行解答
  2. 写出基本的解答斐波那契数列的动态规划代码,后续对此进行更改
        dp[1] = dp[2] = 1;
        for (int i = 3; ; i++) {
            dp[i] = dp[i - 1] + dp[i - 2];
        }
  1. 因为输入的数据会出现不以1,1,2...开头的数据,而是2,2,4,6 ....等等,我们不能只计算以1开始的斐波那契数列,所以我们暴力遍历1-1000000开始的所有数列,并以修改次数最小的那次遍历作为答案,所以我们可以定义函数int dp(int start),返回以start开始的数列与原数组需要修改的次数
    public static int dp(int start) {
        // range代表dp数组的范围,因为dp数组大小只有100,遍历arr数组会超过dp数组的范围
        int range = 2;
        dp[1] = dp[2] = start;
        for (int i = 3; ; i++) {
            dp[i] = dp[i - 1] + dp[i - 2];
            // 数据范围在1000000以内
            if (dp[i] > 1000000) break;
            range++;
        }
        int ans = 0;
        for (int i = 1; i <= range; i++) {
            if (arr[i] == dp[i]) {
                ans++;
            }
        }
        return n - ans;
    }
  1. 暴力遍历,答案为每一个数字开始的数组中修改最少次数的那一次
        int ans = Integer.MAX_VALUE;
        for (int i = 1; i <= 1000000; i++) {
            int cur = dp(i);
            ans = Integer.min(cur, ans);
        }
        System.out.println(ans);
  1. 需要注意一点,就是我为什么会暴力遍历1-1000000 的dp数列,因为求斐波那契数列的过程非常快,然后剪枝掉超过数据范围的循环,因为以1开始的斐波那契数列在31项时就会超过1000000,那么每次遍历不会循环2(31)次,所以可以暴力解此题

完整代码

package lanqiao.java13cFinal;

import java.util.Scanner;

public class E {
    static int N = 100005;
    static int n;
    static int[] arr = new int[N];
    static int[] dp = new int[100];

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();
        for (int i = 1; i <= n; i++) {
            arr[i] = sc.nextInt();
        }
        int ans = Integer.MAX_VALUE;
        for (int i = 1; i <= 1000000; i++) {
            int cur = dp(i);
            ans = Integer.min(cur, ans);
        }
        System.out.println(ans);
    }

    public static int dp(int start) {
        int range = 2;
        dp[1] = dp[2] = start;
        for (int i = 3; ; i++) {
            dp[i] = dp[i - 1] + dp[i - 2];
            if (dp[i] > 1000000) break;
            range++;
        }
        int ans = 0;
        for (int i = 1; i <= range; i++) {
            if (arr[i] == dp[i]) {
                ans++;
            }
        }
        return n - ans;
    }
}

标签:斐波,数列,真题,int,蓝桥,数组,那契,dp
From: https://www.cnblogs.com/zhexian233/p/17426715.html

相关文章

  • 每日一练 | 网络工程师软考真题 Day8
    1、某客户端采用ping命令检测网络连接故障时,发现可以ping通127.0.0.1及本机的IP地址,但无法ping通同一网段内其他工作正常的计算机的IP地址。该客户端的故障可能是    。A.TCP/IP协议不能正常工作B.本机网卡不能正常工作C.本机网络接口故障D.DNS效劳器地址设置错误2、SNMP代理使......
  • 斐波那契数列的实现
    斐波那契数列(Fibonaccisequence),又称黄金分割数列、因数学家列昂纳多·斐波那契(LeonardodaFibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、34、……在数学上,斐波纳契数列以如下被以递归的方法定义:F(0)=0,F(1)=1,F(n)=F(n-1)+F(......
  • 【蓝桥杯集训·每日一题】AcWing 3728. 城市通电
    写在前面本人CSDN博客主页:这里一、题目1、原题链接3728.城市通电2、题目描述平面上遍布着n座城市,编号1∼n。第i座城市的位置坐标为(xi,yi)。不同城市的位置有可能重合。现在要通过建立发电站和搭建电线的方式给每座城市都通电。一个城市如果建有发电站,或者通过电线直接或间......
  • Python编写输出斐波那契数列的前n项
    以下是一个使用Python编写的程序代码,可以计算并输出斐波那契数列的前n项(n由用户输入):n=int(input("请输入斐波那契数列的项数:"))a,b=0,1foriinrange(n):print(b,end="")a,b=b,a+b代码解释:用户输入斐波那契数列的项数n,并使用int()函数将输入的字符串......
  • [每天例题]蓝桥杯 C语言 次数差
    次数差题目  思路分析1.通过字符型数组接收字符串,通过整形数组确定字母出现的次数2.通过for—if寻找出现次数最多与最少的字母,注意,这里有个坑,出现次数最少的字母至少出现一次代码#include<stdio.h>intmain(){ chars[1000]; intnum[26]={0}; intmax=-1,min=10......
  • APIO真题选做
    [APIO2020]粉刷墙壁​ 将长度为\(n\)的墙壁涂色,共有\(k\)种颜色,第\(i\)段墙壁期望的颜色为\(c_i\)。有\(m\)个粉刷公司,第\(i\)个粉刷公司可以涂\(a_i\)种颜色(是给定的)。现在可以提出若干个形如\(x\;y\;(0\lex<m,0\ley\len-m)\)的要求,只有当对于所有的\(0\le......
  • [每天例题]蓝桥杯 C语言 回文日期
    回文日期题目    思路分析1.由于题目要求是找到一定范围日期内的回文日期,所以我们可以采用for遍历日期2.再调用函数先判断闰年,再进行日期合法判断,最后再进行回文数判断3.注意,该日期范围包含起始和结束这两个日期,这里会有一个案例挖坑代码#include<stdio.h>int......
  • [每天例题]蓝桥杯 C语言 笨小猴
    笨小猴题目  思路分析1.首先难点是找出出现次数最多与最少的字母,我们可以通过建立两个数组,一个是字符数组,用来存储字符串,一个是整形数组,用来记录每个字母对应的出现次数,然后再使用for—if配合找出最大最小数2,第二个可以通过调用函数来确定差值是否为素数代码#include<......
  • 每日一练 | 网络工程师软考真题 Day1
    1、内存采用段式存储管理有许多优点,但    不是其优点。A.分段是信息逻辑单位,用户不可见B.各段程序的修改互不影响C.地址变换速度快、内存碎片少D.便于多道程序共享主存的某些段2、现有四级指令流水线,分别完成取指、取作的时间依次为数、运算、传送结果四步操作。假设完成上述操......
  • 斐波那契数列
    一、问题描述。题目求斐波那契数列的40个数,并输出要求:用for循环来遍历所有可能的选项二、设计思路。fibonacci数列可以通过多种方式进行输出,其通项公式为 F(n)=F(n-1)+F(n-2)基本的for循环、数组再到递归,都可以实现。题目要求使用for循环,求前40项第一项和第二项都是1,我们可以用a,b分别......