Description###

windy在有向图中迷路了。 该有向图有 N 个节点,windy从节点 0 出发,他必须恰好在 T 时刻到达节点 N-1。 现在给出该有向图,你能告诉windy总共有多少种不同的路径吗? 注意:windy不能在某个节点逗留,且通过某有向边的时间严格为给定的时间。

Input###

第一行包含两个整数,N T。 接下来有 N 行,每行一个长度为 N 的字符串。 第i行第j列为'0'表示从节点i到节点j没有边。 为'1'到'9'表示从节点i到节点j需要耗费的时间。

Output###

包含一个整数,可能的路径数,这个数可能很大,只需输出这个数除以2009的余数。

Sample Input###

【输入样例一】

2 2

11

00

【输入样例二】

5 30

12045

07105

47805

12024

12345

Sample Output###

【输出样例一】

1

【样例解释一】

0->0->1

【输出样例二】

852

HINT###

30%的数据,满足 2 <= N <= 5 ; 1 <= T <= 30 。 100%的数据,满足 2 <= N <= 10 ; 1 <= T <= 1000000000 。


想法##

dp方程还是很显然的,设 \(f[i][j]\) 表示在第i时刻到达点j的方案数

$f[i][j]=\sum\limits_{e[k][i]\neq 0} f[j-e[k][i]][k] $ (\(e[i][j]\)为结点i到结点j花费的时间)

然而T这么大肯定是过不了的。

这时注意到n很小,像这种变量一大一小的果断矩阵乘法。

由于\(e[i][j] \leq 9\) , 所以计算某一时间时只会用到前9个时间。

不同于“计算斐波那契数列”那种基本的矩阵乘法,这里的f不是一维的,而是二维的。

但没关系,由于会用到的f值比较少,所以可以把二维强行拉成一维。

像这样:

然后就像普通的矩阵乘法一样搞就好了。


代码##

细节有点多,要想清楚一些。

P.S. 代码中的转移并不是上面所说的那种,而是用\(f[i][j]\)更新\(f[i+e[j][k]][k]\),这样写起来更方便。

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring> #define P 2009 using namespace std; const int SZ = 100; struct matrix{
int a[SZ][SZ];
matrix() { memset(a,0,sizeof(a)); }
void init() { for(int i=0;i<SZ;i++) a[i][i]=1; }
matrix operator * (matrix &b) const{
matrix c;
for(int i=0;i<SZ;i++)
for(int j=0;j<SZ;j++)
for(int k=0;k<SZ;k++)
(c.a[i][j]+=a[i][k]*b.a[k][j])%=P;
return c;
}
matrix operator *= (matrix &b) { return *this=*this*b; }
}; matrix Pow_mod(matrix x,int y){
matrix ret; ret.init();
while(y){
if(y&1) ret*=x;
x*=x;
y>>=1;
}
return ret;
} int n,T;
char e[15][15]; int main()
{
scanf("%d%d",&n,&T);
for(int i=1;i<=n;i++)
scanf("%s",e[i]+1); matrix a,b;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(e[i][j]!='0') {
a.a[(i-1)*9][(j-1)*9+e[i][j]-'0'-1]++;
}
for(int i=1;i<=n;i++)
for(int j=0;j<8;j++) a.a[(i-1)*9+j+1][(i-1)*9+j]++;
b.a[0][0]=1;
a=Pow_mod(a,T);
b*=a;
printf("%d\n",b.a[0][(n-1)*9]); return 0;
}

[bzoj1297] [洛谷P4159] [SCOI2009] 迷路的更多相关文章

  1. bzoj1297 / P4159 [SCOI2009]迷路

    P4159 [SCOI2009]迷路 如果边权只有 0/1 那么不就是一个灰常简单的矩阵快速幂吗! 然鹅边权 $<=9$ 所以我们把每个点拆成9个点! 解决~ #include<iostr ...

  2. BZOJ1026或洛谷2657 [SCOI2009]windy数

    BZOJ原题链接 洛谷原题链接 简单的数位\(DP\),套模板就好. #include<cstdio> #include<cstring> using namespace st ...

  3. 【题解】洛谷P4158 [SCOI2009] 粉刷匠(DP)

    次元传送门:洛谷P4158 思路 f[i][j][k][0/1]表示在坐标为(i,j)的格子 已经涂了k次 (0是此格子涂错 1是此格子涂对)涂对的格子数 显然的是 每次换行都要增加一次次数 那么当j ...

  4. 洛谷 P2657 [SCOI2009]windy数 解题报告

    P2657 [SCOI2009]windy数 题目描述 \(\tt{windy}\)定义了一种\(\tt{windy}\)数.不含前导零且相邻两个数字之差至少为\(2\)的正整数被称为\(\tt{wi ...

  5. 洛谷——P2657 [SCOI2009]windy数

    P2657 [SCOI2009]windy数 题目大意: windy定义了一种windy数.不含前导零且相邻两个数字之差至少为2的正整数被称为windy数. windy想知道, 在A和B之间,包括A和 ...

  6. C++ 洛谷 P2657 [SCOI2009]windy数 题解

    P2657 [SCOI2009]windy数 同步数位DP 这题还是很简单的啦(差点没做出来 个位打表大佬请离开(包括记搜),我这里讲的是DP!!! 首先Cal(b+1)-Cal(a),大家都懂吧(算 ...

  7. 洛谷P2657 [SCOI2009]windy数 [数位DP,记忆化搜索]

    题目传送门 windy数 题目描述 windy定义了一种windy数.不含前导零且相邻两个数字之差至少为2的正整数被称为windy数. windy想知道, 在A和B之间,包括A和B,总共有多少个win ...

  8. 洛谷P2566 [SCOI2009]围豆豆(状压dp+计算几何)

    题面 传送门 题解 首先要解决一个问题,就是怎么判断一个点是否在多边形内部 从这个点向某一个方向做一条射线,如果这条射线和多边形的交点为奇数说明在多边形内,否则在多边形外 然而有一些特殊情况,比方说一 ...

  9. [洛谷P2657][SCOI2009]windy数

    题目大意:不含前导零且相邻两个数字之差至少为$2$的正整数被称为$windy$数.问$[A, B]$内有多少个$windy$数? 题解:$f_{i, j}$表示数有$i$位,最高位为$j$(可能为$0 ...

随机推荐

  1. H3C 端口隔离配置举例

  2. JS的防抖与节流学习笔记

    防抖(debounce):当持续触发事件时,在一定的时间段内,只有最后一次触发的事件才会执行. 例: function debounce(fn, wait) { var timer = null; r ...

  3. dotnet core 发布只带必要的依赖文件

    在使用 dotnet core 发布独立项目的时候,会带上大量依赖的库,但是通过微软提供的工具可以去掉一些在代码没有用到的库. 本文介绍的工具是 Microsoft.Packaging.Tools.T ...

  4. 【47.40%】【BZOJ 1875】[SDOI2009]HH去散步

    Time Limit: 20 Sec  Memory Limit: 64 MB Submit: 1363  Solved: 646 [Submit][Status][Discuss] Descript ...

  5. SpringBoot优先级

    1.配置文件 application.properties和application.yml文件可以放在以下四个位置: 外置,在相对于应用程序运行目录的/congfig子目录里. 外置,在应用程序运行的 ...

  6. C++虚继承初识

    struct Employee { ... }; struct Manager : Employee { ... }; struct Worker : Employee { ... }; struct ...

  7. 027.MFC_映射消息

    映射消息MFC中的消息映射宏 DECLARE_MESSAGE_MAP BEGIN_MEASSAGE_MAP END_MESSAGE_MAP向导自动映射消息手动添加映射消息 MFC会帮我们自动映射大部分 ...

  8. 超简单!pytorch入门教程(二):Autograd

    一.autograd自动微分 autograd是专门为了BP算法设计的,所以这autograd只对输出值为标量的有用,因为损失函数的输出是一个标量.如果y是一个向量,那么backward()函数就会失 ...

  9. RecursiveTask和RecursiveAction的使用总结

    一:什么是Fork/Join框架    Fork/Join框架是Java7提供了的一个用于并行执行任务的框架, 是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架.我们再通 ...

  10. Controller中页面跳转完后页面的样式全消失的解决办法

    问题的原因应该是在controller中进行页面跳转时当前文件的路径变了 解决办法: 1.在jsp页面中<%@ page language="java" contentTyp ...