Description

Input
Output
Sample Input
3 8 4 7 4 8
Sample Output
6 2 1
记录dp[i][4]为队伍长度为i时的四种状态mm mf fm ff
那么(mm)dp[i][0] = dp[i-1][0] + dp[i-1][2];
(mf)dp[i][1] = dp[i-1][0] ;
(fm)dp[i][2] = dp[i-1][1] + dp[i-1][3] ;
(ff)dp[i][3] = dp[i-1][1] ;
那么就可以使用矩阵优化
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;
struct node{
int a[5][5] ;
int n ;
};
node mul(node p,node q,int m)
{
int i , j , k ;
node s ;
s.n = p.n ;
for(i = 0 ; i < p.n ; i++)
for(j = 0 ; j < p.n ; j++)
{
s.a[i][j] = 0 ;
for(k = 0 ; k < p.n ; k++)
s.a[i][j] = ( s.a[i][j] + p.a[i][k] * q.a[k][j] ) % m ;
}
return s ;
}
node pow(node p,int k,int m)
{
if( k == 1 )
return p ;
node s = pow(p,k/2,m) ;
s = mul(s,s,m) ;
if( k%2 )
s = mul(s,p,m) ;
return s ;
}
int main()
{
int i , j , l , m ;
node p , s ;
p.n = 4 ;
memset(p.a,0,sizeof(p.a)) ;
p.a[0][0] = p.a[0][1] = 1 ;
p.a[1][2] = p.a[1][3] = 1 ;
p.a[2][0] = 1 ;
p.a[3][2] = 1 ;
while( scanf("%d %d", &l, &m) != EOF )
{
if(l == 0 )
{
printf("1\n") ;
continue ;
}
else if( l == 1 )
{
printf("2\n") ;
continue ;
}
else if( l == 2 )
{
printf("4\n") ;
continue ;
}
s = pow(p,l-2,m) ;
int ans = 0 ;
for(i = 0 ; i < 4 ; i++)
for(j = 0 ; j < 4 ; j++)
ans = ( ans + s.a[i][j] ) % m ;
printf("%d\n", ans) ;
}
return 0;
}
原文:http://blog.csdn.net/winddreams/article/details/42805891