九度oj1081递推数列的算法
来源:互联网 发布:上海网络视听产业基地 编辑:程序博客网 时间:2024/05/16 09:27
这个题用到了矩阵二分乘法,之前没接触过这个东西,这个矩阵二分乘法确实不错,从网上学了一篇文章,进入百度搜九度1081就能搜索到的那边文章,从那里,我学到了矩阵二分乘法和递归算法。
可以将原本o(n)的复杂度弄成o(logn),对于这个题!别小看这个n和logn,比如n为1024,logn居然只有10,差太远了,天壤之别,你logn只要算10次,人家要1024次。
关于递归方法和非递归方法,非递归方法很简便但是设计的时候难一些,既然有好的方法,当然要有 追求 好 的 追求。
附上递归(递归的算法和百度里找的那个一致,没什么看头,非常感谢那位仁兄的代码!具体网址我就不写了)和非递归的AC代码。PS:很容易发现这个题的2*2矩阵M的p,q都为1的时候便是Fibonacci数列了,也就是说这个题其实比Fibonacci数列更一般化,学了这么久编程,终于会用非递归的某!种方法解决一下Fibonacci数列的指数型调用次数问题了,当时看deitel的书的时候还想着如何非递归解决,一直没解决。。傻如猪的感觉有没有?。
#include<iostream> using std::cin; using std::cout; using std::endl; #include<cassert> //完成任意2个2*2矩阵相乘 void func(int t[2][2],int s[2][2]) { int tt[2][2]; tt[0][0] = t[0][0]*s[0][0] + t[0][1]*s[1][0]; tt[0][1] = t[0][0]*s[0][1] + t[0][1]*s[1][1]; tt[1][0] = t[1][0]*s[0][0] + t[1][1]*s[1][0]; tt[1][1] = t[1][0]*s[0][1] + t[1][1]*s[1][1]; for(int i=0;i<=1;i++) for(int j=0;j<=1;j++) t[i][j]=tt[i][j]%10000; } //完成sf的kfc次幂 递归函数 void calCur(int sf[2][2], int kfc) { int sd[2][2]={{sf[0][0],sf[0][1]},{sf[1][0],sf[1][1]}}; if(kfc == 1) return; if(kfc % 2 == 1) { calCur(sf,kfc-1); func(sf,sd); } else { calCur(sf,kfc/2); func(sf,sf); } } int main() { int a[2][2]; int a0, a1, p, q, k; int c; while(cin >> a0 >> a1 >> p >> q >> k) { assert(k >= 0); a[0][0] = p,a[0][1] = q; a[1][0] = 1,a[1][1] = 0; if(k == 0) { cout << a0 % 10000 << endl; continue; } if(k == 1) { cout << a1 % 10000 << endl; continue; } calCur(a,k-1); c = a[0][0]*a1 + a[0][1]*a0; cout << c % 10000 << endl; } return 0; } /************************************************************** Problem: 1081 User: true14fans Language: C++ Result: Accepted Time:20 ms Memory:1520 kb ****************************************************************/
#include<iostream>using std::cin;using std::cout;using std::endl;#define M 10000int main(){int a0,a1,p,q,k,kk;int t1,t2,t3,t4;int M00,M01,M10,M11;int temprow1,row1,row2;while(cin>>a0>>a1>>p>>q>>k){if(k==0){cout << a0 << endl;continue;}if(k==1){cout << a1 << endl;continue;}M00=p%M,M01=q%M,M10=1,M11=0;row1=a1,row2=a0;kk=k-1;while(kk>=1){if(kk%2==0){//临时矩阵存当前分割时的矩阵,分割矩阵次数递增t1=(M00*M00+M01*M10)%M;t2=(M00*M01+M01*M11)%M;t3=(M10*M00+M11*M10)%M;t4=(M10*M01+M11*M11)%M;M00=t1;M01=t2;M10=t3;M11=t4;kk/=2;}else{temprow1=row1;//没有temprow1就eggs broken吧,我在VC6.0里输入20 1 1 14 (0-5) 括号里面为4时就通不过row1=(M00*row1+M01*row2)%M;row2=(M10*temprow1+M11*row2)%M;--kk;}}cout << row1 << endl;}return 0;}
- 九度oj1081递推数列的算法
- 九度OJ 1081: 递推数列
- 九度OJ 1089 递推数列
- 九度OJ 1081 递推数列 -- 矩阵二分乘法
- 九度OJ 题目1081:递推数列
- 九度OJ 1081:递推数列 (递归,二分法)
- 九度OJ题目1081:递推数列-快速幂
- 九度 oj 题目1081:递推数列
- 九度OJ题目1081:递推数列解题报告
- “斐波那契数列”问题的递推算法
- “斐波那契数列”问题的递推算法
- “斐波那契数列”问题的递推算法
- “斐波那契数列”问题的递推算法
- “斐波那契数列”问题的递推算法
- “斐波那契数列”问题的递推算法
- “斐波那契数列”问题的递推算法
- “斐波那契数列”问题的递推算法
- “斐波那契数列”问题的递推算法
- 黑马程序员-基础-IO流1
- Java动态执行可配置的逻辑
- 动态更改JVM里的class
- tar.gz文件的安装
- BST中所有结点之和(设结点个数为n,且中序遍历为等差数列)
- 九度oj1081递推数列的算法
- 通通WPF随笔(3)——艺术二维码素材生成器
- ubuntu下的wireshark编译安装
- cocos2d-x学习之路(8)--重构项目
- 黑马程序员-基础-IO流2
- DIV CSS left right top bottom定位
- ubuntu12.04-64位 装toolchain出错
- Android分享功能
- Web.Config文件中使用configSource