How many ways?? 矩阵

分析

这个题又是特殊的最短路问题
等等再说矩阵的问题,因为这个题的范围比较小,所以。。。可以写一个计数DP来解决。
估计看一眼代码就可以明白了。

#include
#include
#include
const int N=1e2+10;
int dis[N][N],to[N][N];
int main(){
	int n,m;
	while(~scanf("%d%d",&n,&m)){
		if(n==0&&m==0)return 0;
		memset(to,0,sizeof(to));
		for(int i=1;i<=m;i++){
			int a,b;
			scanf("%d%d",&a,&b);
			to[a][b]=1;
		}
		int T;
		scanf("%d",&T);
		while(T--){
			int a,b,k;
			memset(dis,0,sizeof(dis));
			scanf("%d%d%d",&a,&b,&k);
			dis[0][a]=1;
			for(int x=1;x<=k;x++){
				for(int i=0;i

因为时间复杂度的问题,所以这个跑起来比矩阵还要快。
但是如果把\(k\)的范围调大而\(n\)的范围不变,这样就会T,\(k\)是想多大就多大的,因为点可以重复经过,所以这题又被数据坑了?
矩阵的题也写过很多次了,敏感的话可以直接写出答案就是\(A^k\)这个矩阵中对应的点的值。
可以这么考虑,如果有\(dis[i][k]=a,dis[k][j]=b,i->k,k->j\)均只走了一步,那么根据分步乘法,走两步时\(dis[i][j]+=dis[i][k]×dis[k][j]\),正好满足矩阵运算的规则。
之前一直没有证明矩阵快速幂的正确性,要证明这个,只需要证明它满足结合律就行。

首先我们证明

设 为 的矩阵,

所以 ,即

现在进行归纳证明,假设在 时对 个矩阵相乘满足结合律,证明在 时也满足结合律

我们现在试图证明对任意顺序做乘法的 ,都与 相等

考虑任意顺序做乘法的矩阵,找到最后一次相乘的乘号(即没有被任何一个括号包含的乘号),考虑这个乘号两边的矩阵,不妨设左边共有 个矩阵,右边共有 个矩阵,那么由于 0"> ,所以 ,所以根据归纳假设,左边可以写成 ,右边可以写成

然后,因为我们知道了 满足结合律,我们可以将 写成 的形式,然后一层一层将右侧的括号拆掉即可

所以任意顺序相乘的 都相等,等于

现在证明出了对于 时结合律也成立,所以对任意 , 个矩阵相乘符合结合律。

证毕。 ~~我相信现在你对矩阵快速幂已经熟能生巧了~~

你可能感兴趣的:(How many ways?? 矩阵)