题意:求序列数。这个序列中有k种珍珠,而珍珠一共也只有K种,这个序列的长度不小于1,不大于n.
做法:建立状态 dp[i][j]=dp[i-1][j]*j+dp[i-1][j-1]*(k-j+1),而0<=j<=k,所以可以建立两个矩阵,t,m
1000.... dp[i][0] 而ans=dp[i][0]+dp[i][1]+dp[i][2]....dp[i][n];可用累加的方法,算出ans,就是把t的长宽均变成k+2,t[k]+1[k]=t[k+1][k+1]=1;
dp[i][1]
. .......
.
.
00..i.k-i+1.... *
#include <iostream>//谢大神帮忙
#include<cstdio>
#include<cstring>
#define LL long long
#define mod 1234567891
using namespace std;
typedef class matrix
{
public:
int n,m;
LL mat[32][32];
void init(void)
{
memset(mat,0,sizeof(mat));
}
friend matrix operator *(const matrix &,const matrix &);
}matrix;
matrix operator *(const matrix &a,const matrix &b)
{
matrix tem;
tem.n=a.n;
tem.m=b.m;
int i,j,t;
for(i=0;i<a.n;i++)
for(j=0;j<b.m;j++)
{
tem.mat[i][j]=0;
for(t=0;t<a.m;t++)
tem.mat[i][j]=(tem.mat[i][j]+a.mat[i][t]*b.mat[t][j])%mod;
}
return tem;
}
matrix fn,ans,tem;
int n,k;
int main()
{
int T;
scanf("%d",&T);
int i;
while(T--)
{
scanf("%d%d",&n,&k);
ans.n=k+2;ans.m=1;
ans.init();
ans.mat[1][0]=k%mod;
fn.init();
fn.m=fn.n=k+2;
for(i=0;i<=k;i++)
{
fn.mat[i][i]=i;
if(i)fn.mat[i][i-1]=k-i+1;
}
fn.mat[k+1][k]=fn.mat[k+1][k+1]=1;
tem.init();
tem.m=tem.n=fn.m;
for(i=0;i<tem.m;i++)
tem.mat[i][i]=1;
n++;
while(n)
{
if(n&1)tem=tem*fn;
fn=fn*fn;
n>>=1;
}
fn=tem;
ans=fn*ans;
printf("%I64d\n",fn.mat[k+1][0]%mod);
}
return 0;
}