• bzoj-4887-dp+矩阵快速幂


    4887: [Tjoi2017]可乐

    Time Limit: 10 Sec  Memory Limit: 64 MB
    Submit: 247  Solved: 170
    [Submit][Status][Discuss]

    Description

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

    Input

    第一行输入两个正整数N,M表示城市个数,M表示道路个数。(1≤N≤30,0≤M≤100)
    接下来M行输入u,v表示u,v之间有一条道路。
    (1≤u,v≤n)保证两座城市之间只有一条路相连。
    最后输入时间t。1<t≤10^6

    Output

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

    Sample Input

    3 2
    1 2
    2 3
    2

    Sample Output

        f[i][j][0/1]表示在i时刻,处于j位置,0表示存活,1表示爆炸的方案个数,f[i][j][0]->f[i+1][j][0],f[i+1][adj[k]][0],f[i+1][j][1] ,f[i][j][1]不能转移因为已经爆炸了。每一秒的状态都只由上一秒决定,考虑使用快速幂加速,(f[i][1][0],f[i][2][0]......f[i][n][0],Si)*A=(f[i+1][1][0],f[i+1][2][0]......f[i+1][n][0],Si+1),A实际上就是表示点的可达关系的矩阵,A[i][j]表示i->j可达,Si表示当前累计 SUM{f[1][][1]+f[2][][1]+...+f[i][][1]},只要把原先N*N的矩阵扩张为(N+1)*(N+1)就好了,最后一列全置1。

        

     1 #include<iostream>
     2 #include<cstring>
     3 #include<queue>
     4 #include<cstdio>
     5 #include<stack>
     6 #include<set>
     7 #include<map>
     8 #include<cmath>
     9 #include<ctime>
    10 #include<time.h> 
    11 #include<algorithm>
    12 #include<bits/stdc++.h>
    13 using namespace std;
    14 #define mp make_pair
    15 #define pb push_back
    16 #define debug puts("debug")
    17 #define LL  long long 
    18 #define ULL unsigned long long 
    19 #define uint unsigned int
    20 #define pii pair<int,int>
    21 #define eps 1e-10
    22 #define inf 0x3f3f3f3f
    23  
    24 struct matrix{
    25     int len;
    26     int a[35][35];
    27     matrix(){
    28         memset(a,0,sizeof(a));
    29     }
    30     matrix& operator*(matrix& tmp){
    31         matrix ans;
    32         ans.len=len;
    33         for(int i=1;i<=len;++i){
    34             for(int j=1;j<=len;++j){
    35                 for(int k=1;k<=len;++k){
    36                     ans.a[i][k]+=a[i][j]*tmp.a[j][k];
    37                     ans.a[i][k]%=2017;
    38                 }
    39             }
    40         }
    41         return ans;
    42     }
    43     
    44 }A,I;
    45 matrix qpow(matrix X,int n){
    46     matrix ans=I;
    47     while(n){
    48         if(n&1) ans=ans*X;
    49         X=X*X;
    50         n>>=1;
    51     }
    52     return ans;
    53 }
    54 int main(){
    55     int n,m,i,j,k,t;
    56     scanf("%d%d",&n,&m);
    57     A.len=I.len=n+1;
    58     for(i=1;i<=n+1;++i) A.a[i][i]=I.a[i][i]=1;
    59     int u,v;
    60     while(m--){
    61         scanf("%d%d",&u,&v);
    62         A.a[u][v]=1;
    63         A.a[v][u]=1;
    64     }
    65     for(i=1;i<=n+1;i++)A.a[i][n+1]=1;
    66     scanf("%d",&t);
    67     cout<<qpow(A,t+1).a[1][n+1]<<endl;
    68     return 0;
    69 }
  • 相关阅读:
    运算符、基本数据类型-----整型、字符串
    练习题
    python安装与初识(python起源、分类,if语句、while语句、基本数据类型、变量的命名)
    hdu2187悼念512汶川大地震遇难同胞——老人是真饿了(贪心 简单题)
    牛客小白月赛9 A签到(分数取模,逆元)
    牛客小白月赛9H论如何出一道水题(两个连续自然数互质)
    EOJ3134. 短信激活码(大数幂取模)
    EOJ3650 转机折扣(26进制,字符串)
    hdu1042 N!(大数求阶乘)
    hdu2061 Treasure the new start, freshmen!(暴力简单题)
  • 原文地址:https://www.cnblogs.com/zzqc/p/9035236.html
Copyright © 2020-2023  润新知