hdu 2429矩阵乘法 2008 成都
题意:给出了n(n<=30)个串,首先给出一个初始的串,然后两个人轮着从n个串中选择一个串往后边放,要求当前串的第一个字符和上个串的最后一个字符是相同的,有一个成功的串,如果取到成功成功的串就算赢了。 两个人都是随机选串。现在问在m盘内第一个人赢得不同情况有多少种?
思路: 这道题是一道矩阵乘法的题,这一点开始的时候,后来糊涂,弄错了关系。 错了好几次才改过来。 首先根据串的关系,建立一个矩阵A。然后就是求出A+A^3+A^5...+ A^(m/2+m%2);这里推出了一个东西就是
(S2n A) (A^2, 0) = (S2n+2 A)
(S2*n-1 E) (A, E) (S2*n+1 E)
由这个关系可以利用矩阵的快速幂算出答案。
开始的时候糊涂了, 算了一个 sum (A^i),以至于wa了好几次
AC代码:
View Code
#include <iostream> #include <cstdio> #include <cstring> #include <string> #include <queue> #include <algorithm> using namespace std; const int N = 65, P = 10001; int map[N][N], n, s, t, m, nn; char str[N][12], ss[12],st[12]; void mul(int a[][N], int b[][N]); void init() { int len; scanf("%d", &n); for(int i=1; i<=n; i++) { scanf("%s", str[i]); } memset(map, 0, sizeof(map)); for(int i=1; i<=n; i++) { len = strlen(str[i]); for(int j=1; j<=n; j++) { if(str[i][len-1] == str[j][0]) map[i][j] = 1; } } for(int i=1; i<=n; i++) { for(int j=1; j<=n; j++) { map[i+n][j] = map[i][j]; } map[i+n][i+n] = 1; } mul(map, map); scanf("%s", ss); scanf("%s", st); for(int i=1; i<=n; i++) { if(strcmp(ss, str[i]) == 0) s = i; if(strcmp(st, str[i]) == 0) t = i; } nn = n; n *= 2; scanf("%d", &m); } void mul(int a[][N], int b[][N]) { int i,j,k; int c[N][N]; for(i = 1; i <= n; i++) for(j = 1; j <= n; j++) { c[i][j] = 0; for(k = 1; k <= n; k++) { c[i][j] = c[i][j] + a[i][k]*b[k][j]; c[i][j] = c[i][j] % P; } } for(i = 1; i <= n; i++) for(j = 1; j <= n; j++) a[i][j] = c[i][j]; } void solve() { int i,j,k; int ans; int arraya[N][N],arrayb[N][N]; memset(arraya,0,sizeof(arraya)); for(i = 1; i <= n; i++) arraya[i][i] = 1; for(i = 1; i <= n; i++) for(j = 1; j <= n; j++) arrayb[i][j] = map[i][j]; m = (m+1)/2; while(m) { if(1&m) mul(arraya,arrayb); mul(arrayb,arrayb); m = m>>1; } memset(arrayb, 0, sizeof(arrayb)); for(int i=1; i<=nn; i++) { for(int j=1; j<=nn; j++) { arrayb[i][j+nn] = map[i+nn][j]; } arrayb[i+nn][i+nn] = 1; } mul(arrayb,arraya); printf("%d\n",arrayb[s+nn][t]); } int main() { int t; // freopen("t.txt", "r", stdin); scanf("%d", &t); while(t--) { init(); solve(); } return 0; }


浙公网安备 33010602011771号