TJOI2017 可乐(矩阵快速幂)

本文探讨了一种在给定城市图中,计算机器人在特定时间内可能的行为方案数的方法。通过建立邻接矩阵并使用矩阵快速幂算法,解决了大规模时间步长下的路径计数问题,适用于111号城市上机器人的随机移动行为。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description

机器人初始在 111 号城市上。机器人有三种行为:停在原地、下一个相邻的城市、自爆。它每一秒都会随机触发一种行为。现在给出图,问经过了 ttt 秒, 机器人的行为方案数是多少?

1<t≤109,1≤N≤30,0<M<1001<t \leq 10^{9}, 1 \leq N \leq 30,0<M<1001<t109,1N30,0<M<100

Solution

地图很小,先建出邻接矩阵。对于停在原地,让 fi,i=1f_{i,i} = 1fi,i=1,对于自爆,可以建一个虚拟节点 000,然后让所有的点都向它连一条有向边,即为 fi,0=1f_{i,0} = 1fi,0=1

考虑 dp 的过程,设 gi,j,kg_{i,j,k}gi,j,k 为从 iiijjj 走了 kkk 步的方案数,可以发现 kkk 这一维可以滚动掉。那么初始状态即为 gi,j=fi,jg_{i,j} = f_{i,j}gi,j=fi,j。运用 Floyd 的思想,转移为

fi,j=∑k=1nfi,k×fk,j f_{i,j} = \sum_{k=1}^n f_{i,k} \times f_{k,j} fi,j=k=1nfi,k×fk,j

可以发现这是矩阵乘法,所以矩阵快速幂搞定。

时间复杂度 O(n3log⁡t)O(n^3 \log t)O(n3logt)

Code

挂个矩阵快速幂的模板

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 100 + 5, INF = 0x3f3f3f3f, mod = 1e9 + 7;
inline int read() {
	int x = 0, f = 0; char ch = 0;
	while (!isdigit(ch)) f |= ch == '-', ch = getchar();
	while (isdigit(ch)) x = (x << 3) + (x << 1) + (ch ^ 48), ch = getchar();
	return f ? -x : x;
}
int n;
struct mat {
	int m[N][N];
	mat() {
		memset(m, 0, sizeof(m));
		for (int i = 0; i < N; i++) m[i][i] = 1;
	}
};


mat mul(mat a, mat b) {
	mat c;
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= n; j++) {
			c.m[i][j] = 0; //Mention! 
			for (int k = 1; k <= n; k++) 
				c.m[i][j] += a.m[i][k] * b.m[k][j] % mod;
			c.m[i][j] %= mod;	
		}
	return c;
}
mat ksm(mat a, int k) {
	mat res;
	while (k) {
		if (k & 1) res = mul(res, a);
		k >>= 1;
		a = mul(a, a);
	}
	return res;
}
signed main() {
	n = read(); int k = read();
	
	mat a; 
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= n; j++)
			a.m[i][j] = read();
	mat ans = ksm(a, k);
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++)
			printf("%lld ", ans.m[i][j]);
		puts("");
	}		
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值