标签:style blog http color os io ar for 2014
题意:男为f,女为m,求在长度为L的队列中不存在fmf,fff这样子序列的序列的个数。
思路:又是递推题,假设长度为L的队列中存在的序列个数为f(L),那么考虑最后一个放的字母,假设最后一个放m,那么前L-1个可以随意排列,即个数为f(L - 1);如果最后一个放f,那么考虑后两个字母,可能出现的情况为ff,mf,这样比较难判断是否符合题目要求的,所以我们考虑后三个字母,可能出现的情况就为fff,mff,fmf,mmf,显而易见mff,mmf符合题意。当后三个为mmf时,前L-3个可以随意排列,即个数为f(L - 3),当为mff时,可能出现不满足题意的情况,所以我们考虑后四个字母,可能出现的情况为mmff,fmff,只有mmff满足题意,即个数为f(L - 4)。因此可以得到一个递推式f(L) = f(L - 1) + f(L - 3) + f(L - 4)。那么剩下的就是矩阵快速幂的任务了。
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; struct mat{ int s[4][4]; mat() { memset(s, 0, sizeof(s)); } mat operator * (const mat& c) { mat ans; memset(ans.s, 0, sizeof(ans.s)); for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) for (int k = 0; k < 4; k++) ans.s[i][j] = (ans.s[i][j] + s[i][k] * c.s[k][j]); return ans; } mat operator % (int mod) { for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) s[i][j] %= mod; return *this; } }tmp, c; int f[5]; int L, M; void init() { memset(f, 0, sizeof(f)); f[1] = 2; f[2] = 4; f[3] = 6; f[4] = 9; tmp.s[0][0] = f[4]; tmp.s[1][0] = f[3]; tmp.s[2][0] = f[2]; tmp.s[3][0] = f[1]; c.s[0][0] = c.s[0][2] = c.s[0][3] = c.s[1][0] = c.s[2][1] = c.s[3][2] = 1; } mat pow_mod(int k) { if (k == 1) return c; mat a = pow_mod(k / 2); mat ans = a * a % M; if (k % 2) ans = ans * c % M; return ans; } int main() { init(); while (scanf("%d%d", &L, &M) != EOF) { if (L <= 4) printf("%d\n", f[L] % M); else { mat ans = pow_mod(L - 4); ans = ans * tmp; printf("%d\n", ans.s[0][0] % M); } } return 0; }
标签:style blog http color os io ar for 2014
原文地址:http://blog.csdn.net/u011345461/article/details/39028175