题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2604
题意:给出字符串长度L,并且字符串只由‘f‘,‘m‘构成,有2^L种情况,问在其中不包含‘fmf‘,‘fff‘的字符串有多少个。
1.直接递推,虽然过了,但是数据稍微大点就很可能TLE,因为代码上交上去耗时还是比较长的(感觉数据有点水)╭(′▽`)╭(′▽`)╯(
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 6 int a[1111111]; 7 8 int main(){ 9 int l,m; 10 while(scanf("%d %d",&l,&m)!=EOF){ 11 a[0]=1;a[1]=2;a[2]=4;a[3]=6; 12 if(l>=4){ 13 for(int i=4;i<=l;i++){ 14 a[i]=a[i-1]+a[i-3]+a[i-4]; 15 a[i]%=m; 16 } 17 printf("%d\n",a[l]); 18 } 19 else printf("%d\n",a[l]%m); 20 } 21 return 0; 22 }
2.用f(n)表示n个人满足条件的结果
如果最后一个人是m的话,那么前n-1个满足条件即可,就是f(n-1);
如果最后一个是f那么这个还无法推出结果,那么往前再考虑一位:那么后三位可能是:mmf, fmf, mff, fff,其中fff和fmf不满足题意所以不需要考虑,
但是如果是mmf的话那么前n-3可以找满足条件的即:f(n-3),如果是mff的话,再往前考虑一位的话只有mmff满足条件即:f(n-4)
所以f(n)=f(n-1)+f(n-3)+f(n-4),接着就很简单了,和斐波那契的递推式很像。
网上找的一张图,(-?-;),就是这个矩阵。因为f0=1,其实可以n从4就开始取了。
1 #include <iostream> 2 #include <cstring> 3 using namespace std; 4 5 struct matrix{ 6 int m[4][4]; 7 }ans,base; 8 9 int TnT[5]={1,2,4,6,9}; 10 11 int MOD; 12 matrix multi(matrix a,matrix b){ 13 matrix temp; 14 memset(temp.m,0,sizeof(temp.m)); 15 for(int i=0;i<4;i++){ 16 for(int j=0;j<4;j++){ 17 for(int k=0;k<4;k++){ 18 temp.m[i][j]+=a.m[i][k]*b.m[k][j]; 19 if(temp.m[i][j]>=MOD) temp.m[i][j]%=MOD; 20 } 21 } 22 } 23 return temp; 24 } 25 26 void init(){ 27 for(int i=0;i<4;i++) 28 for(int j=0;j<4;j++) 29 ans.m[i][j]=(i==j); 30 for(int i=0;i<4;i++) base.m[0][i]=1; 31 base.m[0][1]=0; 32 for(int i=1;i<4;i++) base.m[i][i-1]=1; 33 } 34 35 int fast_mod(int n){ 36 init(); 37 while(n>0){ 38 if(n&1) ans=multi(ans,base); 39 base=multi(base,base); 40 n>>=1; 41 } 42 int res=0; 43 for(int i=0;i<4;i++) res+=ans.m[0][i]*TnT[4-i]%MOD; 44 return res%MOD; 45 } 46 47 int main(){ 48 int n,m; 49 while(cin>>n>>m){ 50 memset(ans.m,0,sizeof(ans.m)); 51 memset(base.m,0,sizeof(base.m)); 52 MOD=m; 53 if(n<=4) cout<<TnT[n]%MOD<<endl; 54 else cout<<fast_mod(n-4)<<endl; 55 } 56 return 0; 57 }
时间: 2024-10-29 16:10:31