hdu5411

来源:互联网 发布:恢复文件软件 免费版 编辑:程序博客网 时间:2024/05/19 10:40

这道题一开始用动规做,超时,因为N*M的复杂度太大了,后来,根据题解,知道,动规,就是一种递推过程,一般可以转化为矩阵乘法,斐波那契数的一种求解方式就是如此,然后就是根据动态转移方程构造矩阵,对于这道题来说,需要长度为0,长度为1,长度为2……的种数加起来,所以在构造时需要考虑在内。这样,这道题就可以在1s内求得答案了。所以,如果下次动规超时时,可以向这方面想一下。

2015.8.29:

这道题也是前几天作为沟通练习给队友讲过,就是构造矩阵,构造矩阵需要多练习。

(食堂的牛肉拉面里面的白萝卜去哪了?)

#include<stdio.h>#include<string.h>#include<iostream>using namespace std;#define N 60#define MOD 2015struct matix{    int ma[N][N];    matix(){        for(int i=0;i<N;i++){            for(int j=0;j<N;j++){                ma[i][j]=0;            }        }    }    matix operator *(const matix another){        matix ans;        for(int i=0;i<N;i++){            for(int j=0;j<N;j++){                for(int k=0;k<N;k++){                    ans.ma[i][k]=(ans.ma[i][k]+ma[i][j]*another.ma[j][k])%MOD;                }            }        }        return ans;    }};matix pow(matix x,int y){    matix ans;    for(int i=0;i<N;i++){        ans.ma[i][i]=1;    }    while(y){        //printf("wo shi da hao ren");        if(y%2){            ans=ans*x;        }        x=x*x;        y=y/2;    }    return ans;}int main(){    int t;    int n,m;    int cou;    int a;    scanf("%d",&t);    while(t--){        scanf("%d%d",&n,&m);        matix now;        for(int i=1;i<=n;i++){            scanf("%d",&cou);            for(int j=1;j<=cou;j++){                scanf("%d",&a);                now.ma[i-1][a-1]=1;            }        }        for(int i=0;i<=n;i++){            now.ma[i][n]=1;        }        for(int i=0;i<n;i++){            now.ma[n][i]=0;        }        /*for(int i=0;i<=n;i++){            for(int j=0;j<=n;j++){                printf("%d ",now.ma[i][j]);            }            printf("\n");        }*/        now=pow(now,m-1);        //printf("%d\n",m-1);        /*for(int i=0;i<=n;i++){            for(int j=0;j<=n;j++){                printf("%d ",now.ma[i][j]);            }            printf("\n");        }*/        int ans=1;        for(int i=0;i<n;i++){            for(int j=0;j<=n;j++){                ans=(ans+now.ma[i][j])%MOD;            }        }        printf("%d\n",ans);    }}


0 0