How many ways? - http://acm.hdu.edu.cn/showproblem.php?pid=2157
分析
- 以样例1的数据为例,S0、S1、S2和S3表示到达0、1、2和3位置的途径数量。
- 初始时刻在0点,故初始时刻有: S0 = 1、 S1 = 0、 S2 = 0、S3 = 0
- 经过 t 步后,
代码
矩阵快速幂【109MS】
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define MXM 25
#define mod(x) ((x)%1000)
int N;
string L;
struct mat{
LL d[MXM][MXM];
mat operator*(const mat x){
mat ret;
LL tmp;
for(int i = 0; i < N; i++){
for(int j = 0; j < N; j++){
tmp = 0;
for(int k = 0; k < N; k++) tmp = mod(tmp+d[i][k]*x.d[k][j]);
ret.d[i][j] = tmp;
}
}
return ret;
}
void init_unit(){
for(int i = 0; i < N; i++)
for(int j = 0; j < N; j++) d[i][j] = i == j ? 1 : 0;
}
void init(){
memset(d, 0, sizeof d);
}
}ma;
mat matrixPow(mat base, int pow){
mat res;
res.init_unit();
while(pow){
if(pow & 1) res = res * base;
base = base * base;
pow >>= 1;
}
return res;
}
int main(){
int M, Q, s, t, A, B, k;
while(scanf("%d%d", &N, &M)) {
if(N == 0 && M == 0) break;
ma.init();
while(M--){
scanf("%d%d", &s, &t);
ma.d[t][s] = 1;
}
scanf("%d", &Q);
while(Q--){
scanf("%d%d%d", &A, &B, &k);
printf("%d\n", matrixPow(ma, k).d[B][A]);
}
}
return 0;
}
动态规划【15MS】
#include<bits/stdc++.h>
using namespace std;
int dp[25][25], mp[25][25], s[110], t[110];
int main(){
int N, M, Q, A, B, k;
while(scanf("%d %d", &N, &M)) {
if(N == 0 && M == 0) break;
memset(s, 0, sizeof s);
memset(t, 0, sizeof t);
memset(mp, 0, sizeof mp);
for(int i = 0; i < M; i++){
scanf("%d %d", s+i, t+i);
if(mp[s[i]][t[i]] == 0) mp[s[i]][t[i]] = 1;
else i--, M--; // 借助邻接矩阵去重边,wa了n次
}
scanf("%d", &Q);
while(Q--){
memset(dp, 0, sizeof dp);
scanf("%d %d %d", &A, &B, &k);
dp[0][A] = 1;
for(int i = 1; i <= k; i++){
for(int j = 0; j < M; j++){
(dp[i][t[j]] += dp[i-1][s[j]]) %= 1000;
}
}
printf("%d\n", dp[k][B]);
}
}
return 0;
}