焦作网络预选赛 acmicpc2018——L题 矩阵快速幂

版权声明:那个,最起码帮我加点人气吧,署个名总行吧 https://blog.csdn.net/qq_41670466/article/details/82851959

题目链接https://nanti.jisuanke.com/t/31721

God Water likes to eat meat, fish and chocolate very much, but unfortunately, the doctor tells him that some sequence of eating will make them poisonous.

Every hour, God Water will eat one kind of food among meat, fish and chocolate. If there are 333 continuous hours when he eats only one kind of food, he will be unhappy. Besides, if there are 333 continuous hours when he eats all kinds of those, with chocolate at the middle hour, it will be dangerous. Moreover, if there are 333 continuous hours when he eats meat or fish at the middle hour, with chocolate at other two hours, it will also be dangerous.

Now, you are the doctor. Can you find out how many different kinds of diet that can make God Water happy and safe during NNN hours? Two kinds of diet are considered the same if they share the same kind of food at the same hour. The answer may be very large, so you only need to give out the answer module 100000000710000000071000000007.

题意就是现在有三种食物,鱼 肉,巧克力,先规定一种食物不能连续吃三次,不能按照鱼 巧克力 肉或者 肉 巧克力 鱼的顺序,同时巧克力在两边鱼或肉在中间也是不被允许的,问在给定时间内有多少种吃法。

  一开始我只会用搜索来做,结果很明显超时,然后就找博客,发现都是矩阵快速幂或者杜教,哎  还是自己太菜,后来就去看别人的博客,竟然看了两天都没看懂,后来想一下还是放弃,对于现在的我来说知道这道题是考的什么知识点就够了,然后去积极的刷基础题,然后再回头看这道题说不定会有收获。

  、

如果不明白这道题为什么要用矩阵快速幂的是因为快速幂可以加快速度,比较方便的得到递推答案。可以去网上搜一下相关博客

也可以看我的第一个博客是个基础题,可以用来领会一下其中的思想。

这道题的递推式就是f(n)=2f(n-1)-f(n-2)+3f(n-3)+2*f(n-4)  如果想不明白这个递推式的话就跟我一样吧。

扫描二维码关注公众号,回复: 3553247 查看本文章

然后就是代码:

#include<bits/stdc++.h>
using namespace std;

const int maxn = 4;
const int mod = 1e9 + 7;
typedef long long ll;

struct Matrix
{
		ll m[maxn][maxn];
		Matrix() {}
		Matrix operator *(Matrix const &b)const
		{
				Matrix pre;
				memset(pre.m, 0, sizeof(pre.m));
				for (int i = 0; i<maxn; i++)
						for (int j = 0; j<maxn; j++)
								for (int k = 0; k<maxn; k++)
								{
										pre.m[i][j] = (pre.m[i][j] + this->m[i][k] * b.m[k][j]) % mod;
								}
				return pre;
		}
};

Matrix Qp(Matrix a, ll n)
{
		Matrix ans;
		memset(ans.m, 0, sizeof(ans.m));
		for (int i = 0; i<maxn; i++)
				ans.m[i][i] = 1;
		while (n>0)
		{
				if (n & 1)
				{
						ans = ans * a;
				}
				a = a * a;
				n >>= 1;
		}
		return ans;
}

int main()
{
		Matrix base;
		//base.m = { 2, -1, 3, 2// 1, 0, 0, 0,//0, 1, 0, 0// 0, 0, 1, 0 };
		memset(base.m, 0, sizeof(base.m));
		base.m[0][0] = 2;
		base.m[0][1] = -1;
		base.m[0][2] = 3;
		base.m[0][3] = 2;
		base.m[1][0] = 1;
		base.m[2][1] = 1;
		base.m[3][2] = 1;
		ll x[maxn] = { 106,46,20,9 };
		int T;
		scanf("%d", &T);
		while (T--)
		{
				ll n;
				scanf("%lld", &n);
				if (n == 1)
						printf("3\n");
				else if (n == 2)
						printf("9\n");
				else if (n == 3)
						printf("20\n");
				else if (n == 4)
						printf("46\n");
				else
				{
						n -= 5;
						ll res = 0;
						Matrix ans = Qp(base, n);
						for (int i = 0; i<maxn; i++)
						{

								res = (res + x[i] * ans.m[0][i]) % mod;
						}
						cout << res << endl;
				}
		}
		//system("pasue");
		return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41670466/article/details/82851959