hdu_2842_Chinese Rings(矩阵快速幂)

本文解析了 HDU 2842 题目的解题思路,该题目要求求解解开 n 个环的最少步骤。通过递推公式 f(n)=f(n-2)+1+f(n-2)+f(n-1) 进行求解,并使用矩阵快速幂的方法提高效率。

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2842

题意:解开第k个环需要先解开前(k-2)个环,并留有第(k-1)环。问解开n环最少需要几步。

题解:

设f(n)表示解开第n环。 
1. 解开n环不能一下子把n-1全解开了,否则第n个就没法拿掉了。 
2. 得先拿掉第n个:先完成f(n-2),然后再拿掉第n环。 
3. 然后放回前(n-2),其实这也是f(n-2),因为是一个逆的过程。 
4. 最后就变成完成f(n-1)了,所以f(n) = f(n-2)+1 + f(n-2) + f(n-1)。

下面是自己写的矩阵模版:

 1 #include<cstdio>
 2 #define F(i,a,b) for(int i=a;i<=b;i++)
 3 
 4 const int maxn=3,mo=200907;//矩阵阶数,取余
 5 int N=2,n;//N为矩阵实际阶数减1
 6 
 7 struct mat{
 8     long long c[maxn][maxn];
 9     void init(){F(i,0,N)F(j,0,N)c[i][j]=0;}
10     mat operator*(mat b){
11         mat M; M.init();
12         F(i,0,N)F(j,0,N)F(k,0,N)M.c[i][j]=(c[i][k]*b.c[k][j]+M.c[i][j])%mo;
13         return M;
14     }
15     mat operator+(mat b){
16         mat M; M.init();
17         F(i,0,N)F(j,0,N)M.c[i][j]=(c[i][j]+b.c[i][j])%mo;
18         return M;
19     }
20     mat operator^(int k){
21         mat ans,tmp;ans.init();
22         F(i,0,N)F(j,0,N)tmp.c[i][j]=c[i][j];
23         F(i,0,N)ans.c[i][i]=1;
24         while(k){
25             if(k&1)ans=ans*tmp;
26             k>>=1,tmp=tmp*tmp;
27         }
28         return ans;
29     }
30 }A[2],ans;
31 
32 int main(){
33     A[0]=(mat){1,2,1,1,0,0,0,0,1},A[1]=(mat){2,0,0,1,0,0,1,0,0};
34     while(~scanf("%d",&n),n){
35         if(n<=2)printf("%d\n",n);
36         else ans=(A[0]^(n-2))*A[1],printf("%lld\n",ans.c[0][0]);
37     }
38     return 0;
39 }
View Code

 



 

转载于:https://www.cnblogs.com/bin-gege/p/5696119.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值