レターオリンピック (情報学オリンピック) で for ループのトピックを実行するとき、フィボナッチ数列があります。最初に思い浮かぶ方法は再帰的解法を使用することです。過去に最も使用された問題は再帰的形式だったためです。 for ループは疑問が多いので、いくつか新しい方法を考えてみましたが、以下は考えたことの一部ですが、これまで思いついたことがなかった方法なので、ここに記録しておきます。
参照元Junyi_noip
フィボナッチ数列
黄金分割数列としても知られるフィボナッチ数列は、数学者レオナルド フィボナッチがウサギの飼育を例にして紹介したものであるため、「ウサギ数列」とも呼ばれます。 、5、8、13、21、34、...; このシーケンスは 3 番目の項目から始まり、各項目は前の 2 つの項目の合計に等しくなります。
従来手法[再帰]
#include<iostream>
using namespace std;
// 斐波那契额数列函数
// n=1和n=2情况下都输出1
// 其他情况下都调用自身方法
int fb(int n)
{
if(n == 1 || n == 2)
return 1;
else
return fb(n-1) + fb(n-2);
}
// 主函数
int main()
{
int n;
cin>>n;
cout<<fb(n);
return 0;
}
上記の方法は理解しやすく、コードも読みやすいですが、時間計算量が高く、無駄なコードが大量に生成されます。
新しい考え方 [依然として再帰的思考に基づいていますが、再帰的実装ではありません]
- 最後から 2 番目の項目と現在知られている最後の項目を表すように変数 n1、n2 を設定します。
- 新しい項目 t を見つけます (t = n1 + n2)。
- 新しい最後から 2 番目の項目は元の最後の項目であるため、n2 = n1 になります。
- t は新しい最後の項目になります (n1 = t)。
- iが3の場合は3番目の項目が取得され、iが4の場合は4番目の項目が取得され、iがkの場合はk番目の項目が取得されます。i を 3 から k までサイクルして、k 番目の項目を見つけます
上記は簡単な説明です。理解できれば、以下の詳細な説明を読む必要はありません。
詳しい説明
因为要求某个斐波那契数列位置上的值,只需求它前两位两个值的和即可
次に、既知の最後の桁の値を n1 として設定し、最後から 2 番目の既知の桁の値を n2 として、求められる値を n0 として設定します。理解できない場合は、
この本とペンで絵を描いてみてください。
コード
#include<iostream>
using namespace std;
int main()
{
// n为要求第几位的值 n2为已知倒数第二项 n1为已知倒数第一项 n0为要求的那个值
int n, n2 = 1, n1 = 1, n0;
cin>>n;//n:第几项
if(n <= 2)//前两项值为1
cout<<1;
else
{
for(int i = 3; i <= n; ++i)
{
n0 = n1 + n2;
n2 = n1;
n1 = n0;
}
cout<<n1;//输出当前求出的最后一项
}
return 0;
}
理解できれば、自分の言語で解くことができます。
私も初心者です。間違いがあれば修正してください。ありがとうございます。!!