hdu 5411 CRB and Puzzle 矩阵快速幂

题意:有n种数量无限的方块,每种方块后可以拼接另一个方块,但是只能拼接给定种类的方块,问最多拼接M次能拼接出多少种不同的样式。

这道题中n只有50,很容易想到矩阵快速幂,毕竟这种题已经烂大街了。然而比赛的时候我居然没有读到这道题!!!!!
重点在于构造转移矩阵,显然如果a后面可以拼接b,那么有 tmp[a][b]=1; 代表a->b有一种转移方式,构造完了之后,对这个矩阵自乘m次,那么矩阵的结果 tmp[a][b] 代表的就是起点为a,终点为b,经过m次转移的方法数,但是我们要求0次转移 1次转移 2次转移 。。。M次转移的总和,所以把最后一列赋为1,就可以了。
第一次写的时候矩阵构造太挫T了,然后优化了一点勉强过了,
第二次和第三次都是优化过的。
优化过的矩阵构造。
代码1:

//author: CHC
//First Edit Time:  2015-08-25 21:13
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <set>
#include <algorithm>
#include <limits>
//#include <time.h>
using namespace std;
typedef long long LL;
const int INF = numeric_limits<int>::max();
const LL LL_INF= numeric_limits<LL>::max();
const int N = 53;
const int mod=2015;
int T,n,m,k,tn;
//C=A*B
void matric_mul(int A[][N],int B[][N],int C[][N]){
    int t[N][N]={0};
    for(int k=0;k<tn;k++){
        for(int i=0;i<tn;i++){
            if(A[i][k]==0)continue;
            for(int j=0;j<tn;j++){
                t[i][j]+=A[i][k]*B[k][j];
                t[i][j]%=mod;
            }
        }
    }
    for(int i=0;i<tn;i++){
        for(int j=0;j<tn;j++){
            C[i][j]=t[i][j];
        }
    }
}
int res[N][N],tmp[N][N];
void print(int A[][N]){
    for(int i=0;i<tn;i++,puts(""))
        for(int j=0;j<tn;j++)printf("%d ",A[i][j]);
    puts("");
}
int q_pow(int nn){
    //printf("res:\n");
    //print(res);
    while(nn>0){
        if(nn&1)matric_mul(res,tmp,res);
        //printf("res:\n");
        //print(res);
        nn>>=1;
        matric_mul(tmp,tmp,tmp);
    }
    int cnt=res[0][n];
    //for(int i=n;i<tn;i++)cnt+=res[0][i];
    return (cnt+1)%mod;
}
void Rd(int &x){
    char ch;
    while((ch=getchar())&&!isdigit(ch));
    x=0;
    do {
        x=(x<<3)+(x<<1)+(ch^48);
    }while((ch=getchar())&&isdigit(ch));
}
int main()
{
    //freopen("1006.in","r",stdin);
    //freopen("10061.out","w",stdout);
    //clock_t now=clock();
    int maxn=0,maxm=0;
    scanf("%d",&T);
    while(T--){
        //scanf("%d%d",&n,&m);
        Rd(n),Rd(m);
        maxn=max(n,maxn),maxm=max(m,maxm);
        tn=n+1;
        memset(tmp,0,sizeof(tmp));
        memset(res,0,sizeof(res));
        for(int i=0,x;i<n;i++){
            //scanf("%d",&k);
            Rd(k);
            for(int j=0;j<k;j++){
                //scanf("%d",&x);
                Rd(x);
                --x;
                tmp[i][x]=1;
                //tmp[i][x+n]=1;
            }
        }
        //for(int i=n;i<tn;i++)tmp[i][i]=1;
        for(int i=0;i<=n;i++)tmp[i][n]=1;
        //print(tmp);
        for(int i=0;i<n;i++)res[0][i]=1;
        res[0][n]=0;
        //print(res);
        printf("%d\n",q_pow(m));
    }
    //printf("%d %d\n",maxn,maxm);
    //printf("%.2lf\n",1.0*(clock()-now)/CLOCKS_PER_SEC);
    return 0;
}
/*
   10
   3 10
   1 2
   1 3
   0
   */

代码2:

//author: CHC
//First Edit Time:  2015-08-25 21:13
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <set>
#include <algorithm>
#include <limits>
//#include <time.h>
using namespace std;
typedef long long LL;
const int INF = numeric_limits<int>::max();
const LL LL_INF= numeric_limits<LL>::max();
const int N = 52;
const int mod=2015;
int T,n,m,k,tn;
//C=A*B
void matric_mul(int A[][N],int B[][N],int C[][N]){
    int t[N][N]={0};
    for(int k=0;k<tn;k++){
        for(int i=0;i<tn;i++){
            if(A[i][k]==0)continue;
            for(int j=0;j<tn;j++){
                t[i][j]+=A[i][k]*B[k][j];
                t[i][j]%=mod;
            }
        }
    }
    for(int i=0;i<tn;i++){
        for(int j=0;j<tn;j++){
            C[i][j]=t[i][j];
        }
    }
}
int res[N][N],tmp[N][N];
void print(int A[][N]){
    for(int i=0;i<tn;i++,puts(""))
        for(int j=0;j<tn;j++)printf("%d ",A[i][j]);
    puts("");
}
int q_pow(int nn){
    //printf("res:\n");
    //print(res);
    while(nn>0){
        if(nn&1)matric_mul(res,tmp,res);
        //printf("res:\n");
        //print(res);
        nn>>=1;
        matric_mul(tmp,tmp,tmp);
    }
    int cnt=0;
    for(int i=0;i<tn;i++)
        for(int j=0;j<tn;j++)cnt+=res[i][j];
    return (cnt)%mod;
}
void Rd(int &x){
    char ch;
    while((ch=getchar())&&!isdigit(ch));
    x=0;
    do {
        x=(x<<3)+(x<<1)+(ch^48);
    }while((ch=getchar())&&isdigit(ch));
}
int main()
{
    //freopen("1006.in","r",stdin);
    //freopen("10061.out","w",stdout);
    //clock_t now=clock();
    //int maxn=0,maxm=0;
    scanf("%d",&T);
    while(T--){
        //scanf("%d%d",&n,&m);
        Rd(n),Rd(m);
        //maxn=max(n,maxn),maxm=max(m,maxm);
        tn=n+1;
        memset(tmp,0,sizeof(tmp));
        memset(res,0,sizeof(res));
        for(int i=0;i<=n;i++)res[i][i]=1;
        for(int i=0,x;i<n;i++){
            //scanf("%d",&k);
            Rd(k);
            for(int j=0;j<k;j++){
                //scanf("%d",&x);
                Rd(x);
                --x;
                tmp[i][x]=1;
                //tmp[i][x+n]=1;
            }
        }
        for(int i=0;i<=n;i++)tmp[i][n]=1;
        //for(int i=n;i<tn;i++)tmp[i][i]=1;
        //print(tmp);
        //for(int i=0;i<tn;i++)res[0][i]=1;
        //print(res);
        printf("%d\n",q_pow(m-1));
    }
    //printf("%d %d\n",maxn,maxm);
    //printf("%.2lf\n",1.0*(clock()-now)/CLOCKS_PER_SEC);
    return 0;
}
/*
   10
   3 10
   1 2
   1 3
   0
   */

代码3:

//author: CHC
//First Edit Time:  2015-08-25 21:13
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <set>
#include <algorithm>
#include <limits>
//#include <time.h>
using namespace std;
typedef long long LL;
const int INF = numeric_limits<int>::max();
const LL LL_INF= numeric_limits<LL>::max();
const int N = 100;
const int mod=2015;
int T,n,m,k,tn;
//C=A*B
void matric_mul(int A[][N],int B[][N],int C[][N]){
    int t[N][N]={0};
    for(int k=0;k<tn;k++){
        for(int i=0;i<tn;i++){
            if(A[i][k]==0)continue;
            for(int j=0;j<tn;j++){
                t[i][j]+=A[i][k]*B[k][j];
                t[i][j]%=mod;
            }
        }
    }
    for(int i=0;i<tn;i++){
        for(int j=0;j<tn;j++){
            C[i][j]=t[i][j];
        }
    }
}
int res[N][N],tmp[N][N];
void print(int A[][N]){
    for(int i=0;i<tn;i++,puts(""))
        for(int j=0;j<tn;j++)printf("%d ",A[i][j]);
    puts("");
}
int q_pow(int nn){
    //printf("res:\n");
    //print(res);
    while(nn>0){
        if(nn&1)matric_mul(res,tmp,res);
        //printf("res:\n");
        //print(res);
        nn>>=1;
        matric_mul(tmp,tmp,tmp);
    }
    int cnt=0;
    for(int i=n;i<tn;i++)cnt+=res[0][i];
    return (cnt+1)%mod;
}
void Rd(int &x){
    char ch;
    while((ch=getchar())&&!isdigit(ch));
    x=0;
    do {
        x=(x<<3)+(x<<1)+(ch^48);
    }while((ch=getchar())&&isdigit(ch));
}
int main()
{
    //freopen("1006.in","r",stdin);
    //freopen("10061.out","w",stdout);
    //clock_t now=clock();
    int maxn=0,maxm=0;
    scanf("%d",&T);
    while(T--){
        //scanf("%d%d",&n,&m);
        Rd(n),Rd(m);
        maxn=max(n,maxn),maxm=max(m,maxm);
        tn=2*n;
        memset(tmp,0,sizeof(tmp));
        memset(res,0,sizeof(res));
        for(int i=0,x;i<n;i++){
            //scanf("%d",&k);
            Rd(k);
            for(int j=0;j<k;j++){
                //scanf("%d",&x);
                Rd(x);
                --x;
                tmp[i][x]=1;
                tmp[i][x+n]=1;
            }
        }
        for(int i=n;i<tn;i++)tmp[i][i]=1;
        //print(tmp);
        for(int i=0;i<tn;i++)res[0][i]=1;
        //print(res);
        printf("%d\n",q_pow(m-1));
    }
    //printf("%d %d\n",maxn,maxm);
    //printf("%.2lf\n",1.0*(clock()-now)/CLOCKS_PER_SEC);
    return 0;
}
/*
   10
   3 10
   1 2
   1 3
   0
   */
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、下 4载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、下载 4使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、下载 4使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值