题目:Pendant
链接:http://acm.hdu.edu.cn/showproblem.php?pid=2294
分析:
1)f[i][j]表示长度为i,有j种珍珠的吊坠的数目。
$f[i][j] = (k - j + 1) * f[i - 1][j - 1] + j * f[i - 1][j] $
2)用矩阵来转移.
转移矩阵:
$left[ egin{array}{cccccc} 1 & 0 & 0 & ... & 0 & 0 \ 0 & 1 & k-(2-1) & ... & 0 & 0 \ 0 & 0 & 2 & ... & 0 & 0 \ ... & ... & ... & ... & ... & ... \ 0 & 0 & 0 & ... & k-1 & k-(k-1) \ 0 & 0 & 0 & ... & 0 & k end{array} ight] $
状态矩阵:
$left[ egin{array}{ccccc} sum[i-1] & f[i][1] & f[i][2] & ... & f[i][k] end{array} ight] $
初始矩阵:
$left[ egin{array}{ccccc} 0 & k(f[i][1]的值) & 0 & ... & 0 end{array} ight] $
#include <iostream> #include <cstring> #include <cstdio> #include <cmath> using namespace std; typedef long long LL; const int MOD=1234567891; struct Matrix{ LL n,a[32][32]; void init(int _n,int f){ n=_n; memset(a,0,sizeof a); if(f==-1)return; for(int i=0;i<=n;++i)a[i][i]=1; } }; Matrix operator*(Matrix& A,Matrix& B){ Matrix C;C.init(A.n,-1); for(int i=0;i<=C.n;++i) for(int j=0;j<=C.n;++j) for(int k=0;k<=C.n;++k){ C.a[i][j]+=A.a[i][k]*B.a[k][j]; C.a[i][j]%=MOD; } return C; } Matrix operator^(Matrix A,int n){ Matrix Rt;Rt.init(A.n,0); for(;n;n>>=1){ if(n&1)Rt=Rt*A; A=A*A; } return Rt; } int main(){ int Case;scanf("%d",&Case); Matrix A,T; for(int n,k;Case--;){ scanf("%d%d",&n,&k); memset(T.a,0,sizeof T.a); T.n=k; T.a[0][0]=1;T.a[k][0]=1; T.a[1][1]=1; for(int i=2;i<=k;++i){ T.a[i][i]=i; T.a[i-1][i]=k-i+1; } A=T^n; printf("%lld ",A.a[1][0]*k%MOD); } return 0; }