题目描述
兔子有很强的繁殖能力。1对成年的兔子每个月可以生育一对幼年的兔子,而1对幼年的兔子经过m个月之后,就会长成1对成年的兔子。当一开始有1对成年兔子时,经过d个月以后,共有多少对兔子?你的任务是计算出一对成年兔子经过d个月后,共有多少对兔子,假设整个过程中没有兔子死亡。
输入描述
输入有多组数据,每组占1行,为两个整数m,d(1≤m≤10,1≤d≤100),当m=d=0时表示结束。
输出描述
每行为每组数据对应最后得到的兔子数。
样例
输入
2 3 3 5 0 0
输出
5 9
//分析:
/*
首先是对兔子繁殖的推断:
我们都知道Fibonacci公式,那么我们对原始的f[i]=f[i-1]+f[i-2]来看
f[i-1]为当前兔子数,f[i-2]为当前可生殖兔子数,即兔子生长周期为2
那么我们对于m之前的月份,每月应该只会有一只兔子生殖
而m之后的月份,每个月的兔子生殖数应该是m月之前的兔子个数,即f[i-m];
因此得到公式
f[i]=f[i-1]+1 i<m
f[i]=f[i-1]+f[i-m] i>=m
之后我们看到数据范围月份d在[1,100],当d=100时,n=1时兔子数最大是2^100>long long
所以是一个高精加的题目,但是当数据小于2^128时,我们可以借助结构体来构造一个int128数据类型
之后重载一下+,就可以很轻松的完成这个问题了。
*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e18;
struct int128 {
ll low,hig;
} a[101]= {{1,0},{1,0}};//a[0/1].low=1,a[0/1].hig=0;
int m,d;
int128 operator + (int128 a,int128 b) {
int128 t;
t.low=t.hig=0;
t.low=a.low+b.low;
t.hig=t.low/mod+a.hig+b.hig;
t.low%=mod;
return t;
}//对+的重载
void solve() {
a[0]=a[1]= {1,0};//初始化
d++;//由于题目要求从0月可是,d要加1
for(int i=2; i<=d; i++) {
if(i<m)
a[i]=a[i-1]+a[0];
else
a[i]=a[i-1]+a[i-m];
}
if(a[d].hig)
cout<<a[d].hig;
cout<<a[d].low<<"\n";
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
while(cin>>m>>d&&(m||d))
solve();
return 0;
}