• 【RQNOJ85】三个袋子【矩阵乘法】


    题目大意:

    题目链接:http://www.rqnoj.cn/problem/85
    nn个球装进33个袋子里的总方案数。


    思路:

    出题人十分良心的给出了表:

    nn 1 2 3 4 5 6 7 8 9 10
    方案数 1 2 5 14 41 122 365 1094 3281 9842

    然后就变成了一道找规律的题目。


    40分做法:

    容易发现f[i]=3×f[i1]1f[i]=3 imes f[i-1]-1。暴力递推即可。


    20到100分做法:

    可以发现公式f[i]=3i112f[i]=frac{3^{i-1}-1}{2}。直接用快速幂,多少分要看你打的好不好。。。


    100分做法:

    矩阵乘法加速递推。
    可以发现矩阵:
    在这里插入图片描述
    然后递推即可。


    代码:

    #include <cstdio>
    #include <cstring>
    using namespace std;
    
    int n,MOD,f[3];
    int a[3][3]=
    {
    	{0,0,0},
    	{0,3,0},
    	{0,1,1}
    };
    
    void mul(int f[3],int a[3][3])
    {
    	int c[3];
    	memset(c,0,sizeof(c));
    	for (int i=1;i<=2;i++)
    	 for (int j=1;j<=2;j++)
    	  c[i]=((c[i]+f[j]*a[j][i])%MOD+MOD)%MOD;
    	memcpy(f,c,sizeof(c));
    }
    
    void mulself(int a[3][3])
    {
    	int c[3][3];
    	memset(c,0,sizeof(c));
    	for (int i=1;i<=2;i++)
    	 for (int j=1;j<=2;j++)
    	  for (int k=1;k<=2;k++)
    	   c[i][j]=((c[i][j]+a[i][k]*a[k][j])%MOD+MOD)%MOD;
    	memcpy(a,c,sizeof(c));
    }
    
    int main()
    {
    	scanf("%d%d",&n,&MOD);
    	f[1]=1;
    	f[2]=-1;
    	n--;
    	while (n)
    	{
    		if (n&1) mul(f,a);
    		n>>=1;
    		mulself(a);
    	}
    	printf("%d",f[1]%MOD);
    	return 0;
    }
    
  • 相关阅读:
    每周总结8.18
    每周总结7.28
    每周总结8.25
    每周总结7.21
    每周总结8.11
    每周总结8.4
    大道至简 读后感
    递归进行回文的判断
    课后作业1
    GoodBlogs Websites
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/11998482.html
Copyright © 2020-2023  润新知