对于斐波那契,先给大家一个概念
1 1 2 3 5 8
正如上面的数列,从第三项开始,第三项=前两项之和,也就是
f[0]=1,f[1]=1;
for(i=3;i<=n;i++)
f[i]=f[i-1]+f[i-2];
了解了基本的概念,就直接看题目类型(我目前接触到的)
第一类
低精度的,数值很小的(但是下面这题是高精度的,但是因为经过求余处理后,我把他视为低精度问题)
洛谷P1192 台阶问题
题目描述
有N级的台阶,你一开始在底部,每次可以向上迈最多K级台阶(最少11级),问到达第N级台阶有多少种不同方式。
输入格式
两个正整数N,K。
输出格式
一个正整数,为不同方式数,由于答案可能很大,你需要输出ans mod 100003后的结果。
输入输出样例
输入 #1复制
5 2
输出 #1复制
8
说明/提示
对于20%的数据,有N ≤ 10, K ≤ 3;
对于40%的数据,有N ≤ 1000;
对于100%的数据,有N ≤ 100000,K ≤ 100。
#include<bits/stdc++.h>
using namespace std;
int f[100005],n,k;
int main()
{
cin>>n>>k; //k为最大可走步数
f[0]=1;
for(int i=1;i<=n;i++) //计算第i个元素的值
{
for(int j=1;j<=min(i,k);j++) //min(i,k)这个操作很好,当i>k,取k,反之取i
f[i]=(f[i]+f[i-j])%100003; //f[i]就等于所以能走到第i个位置的和
}
cout<<f[n];
return 0;
}
第二类
高精度 ,大数据
这里需要运用到一个二维数组,每行代表台阶的位置,每列代表个位,十位,百位
以此来精简数据,防止空间暴了,数值过大而计算错误
洛谷P1255 数楼梯
题目描述
楼梯有 N 阶,上楼可以一步上一阶,也可以一步上二阶。
编一个程序,计算共有多少种不同的走法。
输入格式
一个数字,楼梯数。
输出格式
输出走的方式总数。
输入输出样例
输入 #1复制
4
输出 #1复制
5
说明/提示
- 对于 60% 的数据,N≤50;
- 对于 100% 的数据,1≤N≤5000。
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
int n,a[5005][5005],len=1; //len:第i阶代表的数值所能到达的十进制位置
void f(int i){
for(int k=1;k<=len;k++){
a[i][k]=a[i-1][k]+a[i-2][k]; //每一个数的分布(个位,十位,百位分别与前两项的位置相
} 加)
for(int k=1;k<=len;k++){
if(a[i][k]>=10){ //十进制,进位
a[i][k+1]+=a[i][k]/10;
a[i][k]=a[i][k]%10;
if(a[i][len+1])len++;
}
}
}
int main(){
cin>>n;
a[0][1]=1,a[1][1]=1,a[2][1]=2; //problem
for(int i=3;i<=n;i++){
f(i);
}
for(int i=len;i>0;i--){ //逆序输出(最高位到个位)
cout<<a[n][i];
}
return 0;
}
大家可以用洛谷P2437,P4994 检验一下学习成果。
lasting and positive