Aoj 92 Pendant (DP+矩阵)

来源:互联网 发布:大数据营销系统源码 编辑:程序博客网 时间:2024/05/24 01:38

转载请注明出处,谢谢http://blog.csdn.net/acm_cxlove/article/details/7854526       by---cxlove 

题目:有K种颜色的物品,组成长度为1-N的串,问有多少种,而且每种颜色都要出现

http://icpc.ahu.edu.cn/OJ/Problem.aspx?id=92 

原以为是组合计数问题,其实DP就好了

dp[i][j]表示利用j种颜色,长度 为i的串有多少种

dp[i][j]=dp[i-1][j]*j+dp[i-1][j-1]*(k-j+1)

但是长度 N非常大,N*K的时间和空间都无法接受,但是这类的递推问题肯定能用矩阵解决

我们要求的是sigma(dp[i][k]),其中sum[j]=sigma(dp[i][k])   j=>i>=1

对于一个行向量{dp[i-1][1],dp[i-1][2],dp[i-1][3]……dp[i-1][k],sum[i-1]}

构造矩阵mat

| 1   k-1

|      2     k-2

|             3     k-3

|                      4

|                                k    1

|                                      1

矩阵快速幂解决

#include<iostream>#include<cstdio>#include<map>#include<cstring>#include<cmath>#include<vector>#include<algorithm>#include<set>#include<string>#include<queue>#define inf 1<<28#define M 6000005#define N 35#define maxn 300005#define Min(a,b) ((a)<(b)?(a):(b))#define Max(a,b) ((a)>(b)?(a):(b))#define pb(a) push_back(a)#define mem(a,b) memset(a,b,sizeof(a))#define LL long long#define MOD 1234567891#define lson step<<1#define rson step<<1|1#define eps 1e-8#define zero(a) (fabs(a)<eps)using namespace std;struct Matrix{    LL m[N][N];}init,unit;Matrix Mult(Matrix m1,Matrix m2,int n=2){    Matrix ans;    for(int i=0;i<n;i++)        for(int j=0;j<n;j++){            ans.m[i][j]=0;            for(int k=0;k<n;k++)                ans.m[i][j]=((LL)ans.m[i][j]+m1.m[i][k]*m2.m[k][j])%MOD;        }    return ans;}Matrix Pow(Matrix m1,int b,int n=2){    Matrix ans;    for(int i=0;i<n;i++)        for(int j=0;j<n;j++)            ans.m[i][j]=(i==j);    while(b){        if(b&1)            ans=Mult(ans,m1,n);        m1=Mult(m1,m1,n);        b>>=1;    }    return ans;}void debug(Matrix m1,int n=2){    for(int i=0;i<n;i++){        for(int j=0;j<n;j++)            printf("%d ",m1.m[i][j]);        printf("\n");    }}int t,n,k;void Init(){    mem(init.m,0);    for(int i=0;i<k;i++)    {        if(i==0) init.m[0][0]=1;        else{            init.m[i-1][i]=k-i;            init.m[i][i]=i+1;        }    }    init.m[k][k]=1;init.m[k-1][k]=1;}int main(){    scanf("%d",&t);    while(t--)    {        scanf("%d%d",&n,&k);        Init();        unit=Pow(init,n-1,k+1);        printf("%I64d\n",k*(unit.m[0][k-1]+unit.m[0][k])%MOD);  //      debug(init,k+1);    }    return 0;}



原创粉丝点击