• [TJOI 2017]可乐


    Description

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

    Input

    第一行输入两个正整数况N,M,N表示城市个数,M表示道路个数。(1 <= N <=30,0 < M < 100)

    接下来M行输入u,v,表示u,v之间有一条道路。(1<=u,v <= n)保证两座城市之间只有一条路相连。

    最后输入入时间t

    Output

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

    Sample Input

    3 2
    1 2
    2 3
    2

    Sample Output

    8

    HINT

    【样例解释】

    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$:

    $f[i][j][0]$表示第$i$时刻,在城市$j$爆炸的方案数,$f[i][j][1]$表示第i时刻,在城市$j$不爆炸的方案数

    $f[i][j][0]=f[i-1][j][0]+f[i-1][j][1]$,$f[i][j][1]=f[i][j][1]+f[i][k][1]$($k$是$j$的相邻结点)

    这样是要$MLE$的,显然状态的答案只与前一状态相关,直接滚动即可

    可是依旧$T$了。

    我们发现是城市数量很少,用邻接矩阵存。有矩阵的话就可以矩阵加速了。

    我们定义矩阵$S$为$1*(n+1)$答案矩阵,$S[0][0]$表示$t$秒前(包括$t$秒)爆炸的方案总数;$S[0][i]$,$1<=i<=n$表示$t$秒时在点$i$的方案总数,初始$S[0][1]=1$;

    矩阵$T$为$(n+1)*(n+1)$的邻接矩阵,除此之外:注意$T[i][0]=1$,$0<=i<=n$为了统计“爆炸”的情况;$T[i][i]=1$表示停在$i$点不动。

    显然我们需要$S*=T^t$,最后答案就是$sum _{i=0} ^n S[0][i]$。

     1 //It is made by Awson on 2017.10.3
     2 #include <set>
     3 #include <map>
     4 #include <cmath>
     5 #include <ctime>
     6 #include <queue>
     7 #include <stack>
     8 #include <vector>
     9 #include <cstdio>
    10 #include <string>
    11 #include <cstring>
    12 #include <cstdlib>
    13 #include <iostream>
    14 #include <algorithm>
    15 #define LL long long
    16 #define Max(a, b) ((a) > (b) ? (a) : (b))
    17 #define Min(a, b) ((a) < (b) ? (a) : (b))
    18 #define sqr(x) ((x)*(x))
    19 #define insert INSERT
    20 using namespace std;
    21 const int MOD = 2017;
    22 void read(int &x) {
    23     char ch; bool flag = 0;
    24     for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == '-')) || 1); ch = getchar());
    25     for (x = 0; isdigit(ch); x = (x<<1)+(x<<3)+ch-48, ch = getchar());
    26     x *= 1-2*flag;
    27 }
    28 
    29 int n, m, u, v, t;
    30 struct mat {
    31     int a[35][35];
    32     mat () {
    33         memset(a, 0, sizeof(a));
    34     }
    35     mat (int _a[35][35]) {
    36         for (int i = 0; i <= n; i++)
    37             for (int j = 0; j <= n; j++)
    38                 a[i][j] = _a[i][j];
    39     }
    40     mat operator * (const mat &b) const{
    41         mat ans;
    42         for (int i = 0; i <= n; i++)
    43             for (int j = 0; j <= n; j++)
    44                 for (int k = 0; k <= n; k++)
    45                     (ans.a[i][j] += a[i][k]*b.a[k][j]) %= MOD;
    46         return ans;
    47     }
    48 }S, T;
    49 
    50 void work() {
    51     read(n), read(m);
    52     for (int i = 1; i <= m; i++) {
    53         read(u), read(v);
    54         T.a[u][v] = T.a[v][u] = 1;
    55     }
    56     for (int i = 0; i <= n; i++)
    57         T.a[i][0] = T.a[i][i] = 1;
    58     S.a[0][1] = 1;
    59     read(t);
    60     while (t) {
    61         if (t&1) S = S*T;
    62         t >>= 1;
    63         T = T*T;
    64     }
    65     int ans = 0;
    66     for (int i = 0; i <= n; i++)
    67         (ans += S.a[0][i]) %= MOD;
    68     printf("%d
    ", ans);
    69 }
    70 int main() {
    71     work();
    72     return 0;
    73 }
  • 相关阅读:
    微信小程序 选择图片 并上传到服务器
    微信小程序 setData
    python--字典排序
    python--csv文件读写
    机器学习实战笔记--AdaBoost(实例代码)
    机器学习实战笔记--朴素贝叶斯(实例代码)
    python继承 super()
    机器学习实战笔记—决策树(代码讲解)
    java的基本认识
    Delphi制作DLL
  • 原文地址:https://www.cnblogs.com/NaVi-Awson/p/7623944.html
Copyright © 2020-2023  润新知