hdu 2065(递推+矩阵乘法)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2065

思路:递推:

dp[len][0]表示长度为len的全部合法字符串的个数;

dp[len][1]表示长度为len的,仅有A出现奇数次的字符串的个数;

dp[len][2]表示长度为len的,仅有C出现奇数次的字符串的个数;

dp[len][3]表示长度为len的,A,C均出现奇数次的字符串的个数。

于是我们可以得到下列方程:

dp[len][0]=2*dp[len-1][0]+dp[len-1][1]+dp[len-1][2];

dp[len][1]=dp[len-1][0]+2*dp[len-1][1]+dp[len-1][3];

dp[len][2]=dp[len-1][0]+2*dp[len-1][2]+dp[len-1][3];

dp[len][3]=dp[len-1][1]+dp[len-1][2]+2*dp[len-1][3];

于是最终的解即为dp[len][0]。

然后就是求二分求幂了。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 typedef long long LL;
 7 struct Matrix{
 8     int map[4][4];
 9 }mat,U;
10 LL n;
11 
12 void Initiate()
13 {
14     for(int i=0;i<4;i++)
15         for(int j=0;j<4;j++)
16             mat.map[i][j]=1;
17     for(int i=0;i<4;i++)
18         mat.map[i][3-i]=0;
19     for(int i=0;i<4;i++){
20         mat.map[i][i]=2;
21         U.map[i][i]=1;
22     }
23 }
24 
25 Matrix Mul(const Matrix &a,const Matrix &b)
26 {
27     Matrix c;
28     for(int i=0;i<4;i++){
29         for(int j=0;j<4;j++){
30             c.map[i][j]=0;
31             for(int k=0;k<4;k++){
32                 c.map[i][j]+=a.map[i][k]*b.map[k][j];
33             }
34             c.map[i][j]%=100;
35         }
36     }
37     return c;
38 }
39 
40 int Pow(LL n){
41     Matrix p=mat,q=U;
42     while(n){
43         if(n&1)
44             q=Mul(p,q);
45         n>>=1;
46         p=Mul(p,p);
47     }
48     return (q.map[0][0]*2+q.map[0][1]+q.map[0][2])%100;
49 }
50 
51 int main()
52 {
53     int _case;
54     Initiate();
55     while(scanf("%d",&_case),_case)
56     {
57         int t=1;
58         while(_case--){
59             scanf("%I64d",&n);
60             printf("Case %d: %d\n",t++,Pow(n-1));
61         }
62         puts("");
63     }
64     return 0;
65 }
View Code

 

 

posted @ 2013-06-11 00:15  ihge2k  阅读(273)  评论(0编辑  收藏  举报