hdu_2842_Chinese Rings(矩阵快速幂)
2016-06-05 23:06
246 查看
题目连接: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)。
下面是自己写的矩阵模版:
#include<cstdio> #define F(i,a,b) for(int i=a;i<=b;i++) const int maxn=3,mo=200907;//矩阵阶数,取余 int N=2,n;//N为矩阵实际阶数减1 struct mat{ long long c[maxn][maxn]; void init(){F(i,0,N)F(j,0,N)c[i][j]=0;} mat operator*(mat b){ mat M; M.init(); 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; return M; } mat operator+(mat b){ mat M; M.init(); F(i,0,N)F(j,0,N)M.c[i][j]=(c[i][j]+b.c[i][j])%mo; return M; } mat operator^(int k){ mat ans,tmp;ans.init(); F(i,0,N)F(j,0,N)tmp.c[i][j]=c[i][j]; F(i,0,N)ans.c[i][i]=1; while(k){ if(k&1)ans=ans*tmp; k>>=1,tmp=tmp*tmp; } return ans; } }A[2],ans; int main(){ A[0]=(mat){1,2,1,1,0,0,0,0,1},A[1]=(mat){2,0,0,1,0,0,1,0,0}; while(~scanf("%d",&n),n){ if(n<=2)printf("%d\n",n); else ans=(A[0]^(n-2))*A[1],printf("%lld\n",ans.c[0][0]); } return 0; }View Code
相关文章推荐
- python网页提取
- leetcode-Add Two Numbers-2
- 第几天?
- 构建之法 阅读笔记03
- c++第7次实验:最大公约数和最小公倍数
- LLDB调试技巧待续
- 伟哥大数据3:MapReduce
- 【Thrift】Thrift框架原理
- Codeforces 366A:Dima and Guards(水题)
- 重新审视进程间的通信(二)
- C++ STL 基础及应用(6) 容器
- 团队项目第四周
- iOS开发网络篇—HTTP协议
- 利用onekey软件制作win10.gho系统文件的小方法
- 第七次作业
- 变量调节器
- 工作流Activity框架入门(一)
- TCP/IP协议攻击实验3
- C++第七次作业
- c++第七次实验