首页 > 其他分享 >Fibonacci

Fibonacci

时间:2024-04-03 23:23:47浏览次数:22  
标签:mini int st ++ que Fibonacci size

Fibonacci

思路

  • 可以发现, 连续的三个字母不全相同, 所以 | s | \(\le\) 3 * |t|

  • |S| 枚举一下即可(好像能证明但是不会),1e6 左右

  • 所以只要暴力算出来一段 S, 然后枚举起点开始匹配即可

40 分

  • \(O(|S| * |s|)\) 枚举即可

100 分

  • 使用类似倍增的方法
    • st[i][j] 表示从 t[i] 出发, 在 s[j] 中找子序列, 能匹配到 t[st[i][j]]
    • 因为 s[j] = s[j-1] + s[j-2], 所以 st[i][j] = st[i][j-1] + st[i+st[i][j-1]][j-2]
  • 然后考虑怎么枚举起点
    • s[j] 可以拆成 s[j-1] + s[j-2]
    • s[j-1] 可以继续拆, 直到 j = 1 或 0
    • 每次删掉最头上的一个 j = 1 或 0 即可
    • 然后用 st 对剩下的进行匹配

代码

40 分

  • 考场代码
#include <bits/stdc++.h> 
#define int long long
using namespace std;
const int N = 1e5 + 10;

string s1, s2, s;
string t;

signed main(){
//	freopen("1.in", "r", stdin);

	cin >> t;
	s1 = "b";
	s2 = "a";
	for(int i = 2; i; i++){
		s = s2 + s1;
		s1 = s2, s2 = s;
		if(s.size() > (int)6e4){
			break;
		}
	}	
	int mini = (int)1e18, cnt = 0;
	for(int i = 0; i < (int)s.size() - (int)t.size() + 1; i++){
		int step = 0, k = 0;
		for(int j = i; j < (int)s.size(); j++){
			step++; cnt++;
			if(s[j] == t[k]){
				k++;
			}
			if(k == (int)t.size()){
				break;
			}
		}
		if(k == (int)t.size()){
			mini = min(mini, step);
		}
	}
	cout << mini << "\n";
}

100 分

#include <bits/stdc++.h> 
#define int long long
using namespace std;
const int INF = 1e18;
const int N = 1.5e5 + 10;

int n;
int len, p, mini;
int fibo[35], st[N][35];
char t[N];
vector <int> que;

void Calc(int x){
	if(p > n){
		return;
	}
	if(x <= 1 || p + st[p][x] <= n){	// x <= 1 表示递归找到底了
		p += st[p][x];	// 该匹配哪一位了
		len += fibo[x];	// |s|
		return;
	}
	Calc(x - 1), Calc(x - 2);
}

void Solve(){	// 用 st 算挨个在 que 中找子序列的 |s|
	len = 0;	// |s|
	p = 1;	// 该去匹配 t 的第 p 位了(下标从 1 开始)
	for(int i = que.size() - 1; i >= 0; i--){
		Calc(que[i]);
	}
	if(p > n){
		mini = min(mini, len);
	}
}

signed main(){
//	freopen("1.in", "r", stdin);

	cin >> (t + 1);
	n = strlen(t + 1);
	for(int i = 1; i <= n; i++){
        // 初始化: 第一位和 s_0 / s_1 能匹配上
		if(t[i] == 'a'){
			st[i][1] = 1;
		}else{
			st[i][0] = 1;
		}
	}
	
	int up = 31;
	mini = 3 * n;
	for(int i = n; i >= 1; i--){
		for(int j = 2; j <= up; j++){
            // 类似倍增的操作
			st[i][j] = st[i][j - 1] + st[i + st[i][j - 1]][j - 2];
		}
	}
	
	fibo[0] = fibo[1] = 1;
	for(int i = 2; i <= up; i++){
        // 递推斐波那契序列, 用于计算 |s|
		fibo[i] = fibo[i - 1] + fibo[i - 2];
	}
	
	que.push_back(up);
	while(!que.empty()){
		Solve();
		while(que.back() >= 2){
			int ba = que.back();
			que.pop_back();
			que.push_back(ba - 2);
			que.push_back(ba - 1);
		}
		que.pop_back();	// 每次删掉一个最小单位(和 for(int i = 1; i <= n; i++) 没多大区别)
	}
	cout << mini << "\n";
}

标签:mini,int,st,++,que,Fibonacci,size
From: https://www.cnblogs.com/Bubblee/p/18113695

相关文章

  • 佳佳的 Fibonacci
    和lyh想的差不多,我认为我写的会更详细一些。dyc好厉害。完全想不到这样的做法。给你两个整数\(n\),\(m\),让你求以下式子的值。\[T(n)=\sum_{i=1}^{n}f(i)\timesi\bmodm\]对于斐波那契数列\(f(n)=f(n-1)+f(n-2)\)这样的性质,使用前缀和化简式子是个好东西。式子就变......
  • Fibonacci
    #1.Recursionslowdeffibonacci_recursion(n):ifn<=1:returnnelse:returnfibonacci_recursion(n-1)+fibonacci_recursion(n-2)#2.Listsaveeveryvalue,avoidrepeatecomputefastdeffibonacci_list(n):F=[0,1]if......
  • Fibonacci数列
    1.Fibonacci数列-蓝桥云课(lanqiao.cn)题目描述:Fibonacci数列:第1、2项均为1,从第3项开始,每一项都是前两项之和。输入n值,输出Fibonacci数列第n项,该数列前10项为1,1,2,3,5,8,13,21,34,55。输入描述:输入占一行,为n的值,1sns40。输出描述:输出占一行,为Fibonacci数列第n项......
  • 佳佳的 Fibonacci
    题面\(f_x=\begin{cases}1&x\in\{1,2\}\\f_{x-1}+f_{x-2}&x\geq3\\\end{cases}\)求\(1\timesf_1+2\timesf_2+3\timesf_3+…+n\timesf_n\)。解法正常的Fibonacci前n项和\(loj\)如果卡死了用这个:Fibonac......
  • P9825 [ICPC2020 Shanghai R] Fibonacci
    原题链接题解直观的\(O(n)\)算法很容易想到,但是很不幸,挂了所以我们要想到\(O(1)\)的做法考虑到斐波那契数列非常有规律,所以我们找找规律奇,奇,偶,奇,奇,偶。。。code#include<bits/stdc++.h>usingnamespacestd;#definelllonglonglla[5]={0};intmain(){lln......
  • CF1264F Beautiful Fibonacci Problem
    一道比较Beautiful的结论题,初始感觉难以下手,做了后认为在CF3500中不算很难的(逃看到题目中“后18位的子串”,很明显的,我们要求一下Fibonacci数列${mod}10^k$的循环节。实践打表证明这个循环节为$1.5*10^k$但是我们需要一个随Fibonacci下标线性增加,$mod10^k$的值也线性增加的......
  • 2019年-fibonacci数列与黄金分割
    目录题目法一、递归法二、迭代题目法一、递归deffib(n):ifn==1orn==2:return1returnfib(n-1)+fib(n-2)n=int(input())a=fib(n)b=fib(n+1)print("{:.8f}".format(a/b))只通过了60%的测试法二、迭代#动态规划#deffib(n):#dp=[0]*(n+1)#......
  • 打印 Fibonacci 数列:
    #include<stdio.h> voidfibonacci(intn){   inti,num1=0,num2=1,nextNum;      printf("Fibonacciseriesupto%dterms:\n",n);      for(i=1;i<=n;++i){       printf("%d,",num1);       nextNum=num1+......
  • CodeForces 946F Fibonacci String Subsequences
    洛谷传送门CF传送门duel的时候差点不会2400了。套路地,考虑每个\(F(x)\)中与\(s\)相同的子序列的贡献。设这个子序列为\(F(x)_{p_1},F(x)_{p_2},F(x)_{p_3},\ldots,F(x)_{p_n}\)。我们想要它成为一个子序列的子串,那么\(F(x)_{[p_1,p_n]}\)中除了\(p_1\simp_......
  • 【题解】Fibonacci-ish II
    传送门题目分析根据题目范围\(n\le30000\)并且此题可以离线维护这个很恶心的东西,所以我们考虑莫队。由于要求访问到任意一个区间都要求知道它有序之后的序列,所以这个东西可以用权值线段树维护。因此,此题正解是莫队+权值线段树。我们分类讨论一下加上一个数,删除一个数对答案......