奶牛家族(斐波那契数列的快速幂乘矩阵算法)

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;
	}
};
发布了212 篇原创文章 · 获赞 4 · 访问量 8785

猜你喜欢

转载自blog.csdn.net/ShenHang_/article/details/104799215