[洛谷P3758][TJOI2017]可乐

it2025-02-25  28

题目描述

加里敦星球的人们特别喜欢喝可乐。因而,他们的敌对星球研发出了一个可乐机器人,并且放在了加里敦星球的1号城市上。这个可乐机器人有三种行为: 停在原地,去下一个相邻的城市,自爆。它每一秒都会随机触发一种行为。现 在给加里敦星球城市图,在第0秒时可乐机器人在1号城市,问经过了t秒,可乐机器人的行为方案数是多少?

输入输出格式

输入格式

第一行输入两个正整数况N,M,N表示城市个数,M表示道路个数。(1 <= N <=30,0 < M < 100) 接下来M行输入u,v,表示u,v之间有一条道路。(1<=u,v <= n)保证两座城市之间只有一条路相连。 最后输入入时间t

输出格式

输出可乐机器人的行为方案数,答案可能很大,请输出对2017取模后的结果。

输入输出样例

输入样例#1

3 2 1 2 2 3 2

输出样例#1

8

说明

【样例解释】

1 ->爆炸 1 -> 1 ->爆炸 1 -> 2 ->爆炸 1 -> 1 -> 1 1 -> 1 -> 2 1 -> 2 -> 1 1 -> 2 -> 2 1 -> 2 -> 3

【数据范围】

对于20%的pn,有1 < t ≤ 1000 对于100%的pn,有1 < t ≤ 10^6。


想法

很显然的dp n这么小,可以矩阵加速 进行快速幂的矩阵共n+1列,前n列为某个点与其他点的连接情况,最后一列全是1,计算某一秒自爆的方案数


代码

#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #define P 2017 using namespace std; const int N = 35; struct matrix{ int a[N][N]; void clear(){ for(int i=1;i<N;i++) for(int j=1;j<N;j++) a[i][j]=(i==j); } matrix operator * (const matrix &b) const{ matrix c; for(int i=1;i<N;i++) for(int j=1;j<N;j++){ c.a[i][j]=0; for(int k=1;k<N;k++) c.a[i][j]=(c.a[i][j]+(a[i][k]*b.a[k][j])%P)%P; } return c; } }; int n,m,t; matrix map; matrix pow_mod(matrix b,int x){ matrix ret; ret.clear(); while(x){ if(x&1) ret=ret*b; b=b*b; x>>=1; } return ret; } int main() { int u,v; scanf("%d%d",&n,&m); map.clear(); for(int i=0;i<m;i++){ scanf("%d%d",&u,&v); map.a[u][v]=map.a[v][u]=1; } for(int i=1;i<=n+1;i++) map.a[i][n+1]=1; scanf("%d",&t); matrix a; memset(a.a,0,sizeof(a.a)); a.a[1][1]=1; a=a*pow_mod(map,t); int ans=0; for(int i=1;i<=n+1;i++) ans=(ans+a.a[1][i])%P; printf("%d\n",ans); return 0; }

转载于:https://www.cnblogs.com/lindalee/p/8379369.html

相关资源:数据结构—成绩单生成器
最新回复(0)