TX面试题:
已知有一头牛4年后开始生小牛,一次只能生一只,问20年后一共有多少头牛?
这种问题就是简单的递归:
这头奶牛在第四年后能不断生子直到第二十年,其子出生4年后又能不断生子……
代码如下:
#include <iostream>
using namespace std;
int func(int n)//计算当前这头牛在n年中能创造多少后代(包括后代的后代)
{
int sum = 0;
if (n <= 3)return sum;
for (int i = 4; i <= n; i++)
{
sum++; //当前这头牛在第i年生的小牛
sum += func(n - i + 1);//当前这头第i年出生的小牛接下来要产生的后代
}
return sum;
}
int main()
{
int s;
s = func(20);
cout << s + 1 << endl;
system("pause");
return 0;
}
法2:
其实递推公式就是斐波那契数列f(n)=f(n-1)+f(n-3);
int f(int n)
{
if (n == 1)return 1;
if (n == 2)return 1;
if (n == 3)return 1;
if (n == 4)return 2;
return f(n - 1) + f(n - 3);
}
int main()
{
cout << f(20)<< endl;
system("pause");
return 0;
}
法3:
利用快速幂乘矩阵算法求解斐波那契数列。
当n很大时,用递归求解斐波那契数列效率是非常低的,所以要用快速幂乘矩阵算法求解斐波那契数列。将O(n)的时间复杂度,降到O(logn)。
class Cows {
public:
void Multiply(long a[3][3], long b[3][3])//矩阵相乘a=a*b
{
long temp[3][3] = { 0 };
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
for (int k = 0; k < 3; k++)
{
temp[i][j] += a[i][k] * b[k][j] % 1000000007;
temp[i][j] %= 1000000007;
}
}
}
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
a[i][j] = temp[i][j];
}
}
//第1年:1
//第2年:2
//第3年:3
//第4年:4
//第5年:6
//f(n)=f(n-1)+f(n-3)
int countSum(int n) {
if (n <= 4)
return n;
long res[3][3] = { 1,0,0,0,1,0,0,0,1 };//单位阵
long base[3][3] = { 1,0,1,1,0,0,0,1,0 };//要求base矩阵的n-3次方
int num = n - 3;
while (num)
{
if (num % 2)
{
Multiply(res, base);
}
Multiply(base, base); //(base^2) ^ (n/2) ...(base^4) ^ (n/4)...(base^n) ^ (1)
num /= 2;
}
return (res[0][0] * 3 + res[0][1] * 2 + res[0][2] * 1) % 1000000007;
}
};