zoukankan      html  css  js  c++  java
  • 都市环游

    【问题描述】
    因为 SJY 干的奇怪事情过多, SJY 收到了休假的通知,于是他准备在都市间
    来回旅游。SJY 有一辆车子,一开始行驶性能为 0,每过 1 时间行驶性能就会提
    升 1 点。每个城市的道路都有性能要求。SJY 一共有 t 时间休息,一开始他位于
    1 号城市(保证 1 号城市道路要求为 0),他希望在 n 号城市结束旅程。每次穿过
    一条城市间的路会花费 1 时间,当然他也可以停留在一个城市不动而花费 1 时间。
    当且仅当车子的行驶性能大于等于一个城市,我们才能到达那里。 SJY 希望知道,
    旅游的方案模 10086 后的答案。(只要在某一时刻通过的道路存在一条不相同,
    就算不同的方案)

    【数据规模和约定】
    对于 20%的数据,n<=10,t<=80;
    对于 50%的数据,n<=30,t<=80;
    对于 100%的数据,n<=70,m<=1000,t<=100000000,hi<=70。

    题解:

    对于有限制的t<=70, 直接暴力dp求出即可

    然后建立矩阵,矩阵快速幂求解:

    对于辅助矩阵,直接按输入的边弄成邻接矩阵即可,注意对角线要为1

    然后就是把dp数组作为要求的矩阵的第一行,然后对角线赋值为1即可

     1 #include <algorithm>
     2 #include <iostream>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <cstdio>
     6 #include <cmath>
     7 #define RG register
     8 #define il inline
     9 using namespace std;
    10 const int N=75,M=75,mod=10086,E=5005;
    11 int n,m,t,lim[N];
    12 struct edge{
    13     int x,y;
    14 }e[M];
    15 int nxt[E<<1],to[E<<1],head[N],num=0,f[N][N];
    16 void init(int x,int y){
    17     nxt[++num]=head[x];to[num]=y;head[x]=num;
    18 }
    19 struct mat{
    20     int a[N][N];
    21     mat(){for(int i=0;i<N;i++)for(int j=0;j<N;j++)a[i][j]=0;}
    22     //mat(int b[N][N]){for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)a[i][j]=b[i][j];}
    23     mat operator *(const mat &fc){
    24         mat tmp;
    25         for(RG int i=1;i<=n;i++){
    26             for(RG int j=1;j<=n;j++){
    27                 tmp.a[i][j]=0;
    28                 for(RG int k=1;k<=n;k++){
    29                     tmp.a[i][j]+=(a[i][k]*fc.a[k][j]%mod),tmp.a[i][j]%=mod;
    30                 }
    31             }
    32         }
    33         return tmp;
    34     }
    35 };
    36 void work()
    37 {
    38     scanf("%d%d%d",&n,&m,&t);
    39     for(int i=1;i<=n;i++)scanf("%d",&lim[i]);
    40     for(int i=1;i<=m;i++){
    41         scanf("%d%d",&e[i].x,&e[i].y);
    42         init(e[i].x,e[i].y);
    43     }
    44     int u;
    45     f[1][0]=1;
    46     for(int i=1;i<=70;i++){
    47         for(int j=1;j<=n;j++){
    48             f[j][i]+=f[j][i-1];
    49             if(f[j][i]>=mod)f[j][i]-=mod;
    50             if(f[j][i]==0)continue;
    51             for(int k=head[j];k;k=nxt[k]){
    52                 u=to[k];
    53                 if(i>=lim[u])
    54                 {
    55                     u=to[k];
    56                     f[u][i]+=f[j][i-1];
    57                     if(f[u][i]>=mod)f[u][i]-=mod;
    58                 }
    59             }
    60         }
    61     }
    62     if(t<=70){
    63         printf("%d
    ",f[n][t]);
    64         return ;
    65     }
    66     t-=70;
    67     mat S,T;
    68     for(int i=1;i<=n;i++)S.a[1][i]=f[i][70];
    69     for(int i=2;i<=n;i++)S.a[i][i]=1,T.a[i][i]=1;
    70     T.a[1][1]=1;
    71     for(int i=1;i<=m;i++)T.a[e[i].x][e[i].y]++;
    72     while(t){
    73         if(t&1)S=S*T;
    74         T=T*T;t>>=1;
    75     }
    76     printf("%d
    ",S.a[1][n]);
    77 }
    78 int main()
    79 {
    80     freopen("travel.in","r",stdin);
    81     freopen("travel.out","w",stdout);
    82     work();
    83     return 0;
    84 }
  • 相关阅读:
    设计模式---行为变化模式之命令模式(Command)
    设计模式---数据结构模式之职责链模式(Chain of Responsibility)
    设计模式---数据结构模式之迭代器模式(Iterate)
    WinCE全屏手写输入法
    .net下所有DLL(API)查询,转换C#代码
    在线cron表达式生成器
    完全卸载vs2013、vs2015的方法
    java微信 客服接口-发消息 中文乱码
    【路由达人】简单两步搞定小米路由新增功能-DDNS(解析域名地址转向在线工具)
    微信公众平台开发入门教程
  • 原文地址:https://www.cnblogs.com/Yuzao/p/7384459.html
Copyright © 2011-2022 走看看