HDU 2604 递推 + 矩阵快速幂
2016-10-06 18:37
281 查看
HDU 2604
题解:首先, 记长为n的队列的K队列数为f(n);
易求得:f(0) = 0, f(1) = 2, f(2) = 4, f(3) = 6, f(4) = 9.
当n >= 5时, 运用递推关系可推出:
f(n) = f(n - 1) + f(n - 3) + f(n - 4);
具体推导过程如下:
设f(n)为字符串长度为n时复合条件的字符串个数,以字符串最后一个字符为分界点,当最后一个字符为m时前n-1个字符没有限制,即为f(n-1);当最后一个字符为f时就必须去除最后3个字符是fmf和fff的情况,在考虑最后两个字符为mf和ff的情况,显然不行;最后3个字符为fmf、mmf和fff、mff时只有当最后3个字符为mmf时前n-3个字符没有限制,即为f(n-3),当为mff时第n-3个字符可能为f因而对前n-3个字符串有限制;最后4个字符为fmff和mmff时mmff可行。这样就讨论完了字符串的构成情况,得出结论:
f(n)=f(n-1)+f(n-3)+f(n-4)
然后就像fibonacci那样构建矩阵用快速幂取模。。。
code:
题解:首先, 记长为n的队列的K队列数为f(n);
易求得:f(0) = 0, f(1) = 2, f(2) = 4, f(3) = 6, f(4) = 9.
当n >= 5时, 运用递推关系可推出:
f(n) = f(n - 1) + f(n - 3) + f(n - 4);
具体推导过程如下:
设f(n)为字符串长度为n时复合条件的字符串个数,以字符串最后一个字符为分界点,当最后一个字符为m时前n-1个字符没有限制,即为f(n-1);当最后一个字符为f时就必须去除最后3个字符是fmf和fff的情况,在考虑最后两个字符为mf和ff的情况,显然不行;最后3个字符为fmf、mmf和fff、mff时只有当最后3个字符为mmf时前n-3个字符没有限制,即为f(n-3),当为mff时第n-3个字符可能为f因而对前n-3个字符串有限制;最后4个字符为fmff和mmff时mmff可行。这样就讨论完了字符串的构成情况,得出结论:
f(n)=f(n-1)+f(n-3)+f(n-4)
然后就像fibonacci那样构建矩阵用快速幂取模。。。
code:
/* adrui's submission Language : C++ Result : Accepted Love : ll Favorite : Dragon Balls Standing in the Hall of Fame */ #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> using namespace std; #define debug 0 #define LL long long #define mod 7 #define M(a, b) memset(a, b, sizeof(a)) const int maxn = 20 + 5; int a, b; struct Matrix { int mat[4][4]; void init() { M(mat, 0); for (int i = 0; i < 4; i++) mat[i][i] = 1; } }; Matrix operator * (Matrix a, Matrix t) { //矩阵乘法 Matrix c; M(c.mat, 0); for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) { for (int k = 0; k < 4; k++) c.mat[i][j] += (a.mat[i][k] * t.mat[k][j]) % b; c.mat[i][j] %= b; } return c; } Matrix operator ^ (Matrix tmp, int b) { //快速幂 Matrix res; res.init(); while (b) { if (b & 1) res = res * tmp; tmp = tmp * tmp; b >>= 1; } return res; } int main() { #if debug freopen("in.txt", "r", stdin); #endif //debug int ans[] = { 0, 2, 4, 6, 9 }; while (~scanf("%d%d", &a, &b)) { Matrix tmp; M(tmp.mat, 0); //构造底数矩阵 tmp.mat[0][0] = tmp.mat[2][0] = tmp.mat[3][0] = 1; tmp.mat[0][1] = 1; tmp.mat[1][2] = 1; tmp.mat[2][3] = 1; if (a < 4) //直接输出 printf("%d\n", ans[a] % b); else{ Matrix res = tmp ^ (a - 4); //快速幂 int ans1 = 0; for (int i = 0; i < 4; i++) { ans1 = (ans1 + ans[4 - i] * res.mat[i][0]) % b; //和初始矩阵相乘 } printf("%d\n", ans1); //ans } } return 0; }
相关文章推荐
- HDU - 2604 Queuing (递推 + 矩阵快速幂)
- [hdu 2604] Queuing 递推 矩阵快速幂
- hdu 2604 递推 矩阵快速幂
- HDU 2604 Queuing [递推]【矩阵快速幂】
- HDU 2604 Queuing(矩阵快速幂)
- hdu 2604 Queuing 递推/DP 矩阵快速幂 Trie数辅助
- hdu 2604 Queuing 矩阵快速幂
- HDU_2604 矩阵快速幂 较难推的公式
- hdu 2604 Queuing(矩阵快速幂乘法)
- HDU 2604 矩阵快速幂
- HDU - 2604 Queuing 矩阵快速幂
- hdu 2842(矩阵快速幂+递推)
- hdu 2604 Queuing 矩阵快速幂
- hdu 2604 Queuing (矩阵快速幂)
- HDU 2604 Queuing (矩阵快速幂)
- hdu 2604(矩阵快速幂)
- HDU 2604 Queuing DP + 矩阵快速幂
- HDU - 2604 Queuing (矩阵快速幂)
- hdu 2604 queuing dfa dp + 矩阵快速幂
- ZOJ 3690 & HDU 3658 (矩阵快速幂+公式递推)