zoukankan      html  css  js  c++  java
  • 旅行的意义 Gym

    题目链接:

    旅行的意义

     Gym - 102174L 

    题目大意:

    天天身在 11 号城市,他每到达一个旅游城市都会先花一天的时间游玩当地的旅游景点。接下来他也没有明确的目的地,所以第二天他会随机地选择该城市的一条直达线路,花费一天的时间通往下一个旅游城市。当然,如果这个城市的旅游景点太好玩的话,他可能会选择再逗留一天,但是由于假期有限,他在当前的旅游城市最多只能呆 22 天。例如,当天天在城市 CC 时,若城市 CC 有 22 条直达线路分别通往城市 AA 和城市 BB,则在第一天的游玩过后,第二天他有 1313 的可能会选择继续逗留在城市 CC 多游玩一天,但是第三天他一定不会再逗留在城市 CC 了;同时他有 1313 可能会选择立即搭乘直达城市 AA 的高铁;他也有 1313 的可能会选择立即搭乘直达城市 BB的高铁。

    当天天把所有的旅游城市都游玩过后,他也就只能结束这段难忘的五一旅行假期了。现在请聪明的你帮天天提前计算一下,他本次旅行时间的期望是多少呢?

    容易证明天天旅行时间的期望为 PQPQ 的形式,其中 PP 和 QQ 互质,且 Q≢0 (mod 998244353)Q≢0 (mod 998244353)。因此答案请以 PQ1 (mod 998244353)P⋅Q−1 (mod 998244353) 的形式输出,其中 Q1Q−1 表示 QQ 在取模 998244353998244353 下的逆元。

    具体思路:

    dp[u][0]代表当前天天刚到达u这个城市并且玩了一天。

    dp[u][1]代表当前天天打算在u这个城市玩两天。

    当二维是0的时候,

    dp[u][0]+=(dp[to][0]+1)*(size[u]+1).

    // 在城市u已经玩了一天,并且打算用一天的时间乘车去下一个站点

    dp[u][0]+=(dp[u][1])*(size[u]+1);

    // 在城市u再再玩一天。

    dp[u][1]+=(dp[to][0]+1)*(size[u]).

    // 在城市u已经玩了两天了,只能选择继续往下一个城市走。

    AC代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 # define ll long long
     4 # define inf 0x3f3f3f3f
     5 const int mod = 998244353;
     6 const int maxn = 2e5+100;
     7 int dp[maxn][2];
     8 vector<int>Edge[maxn];
     9 ll inv[maxn];
    10 void init()
    11 {
    12     inv[1]=1;
    13     for(int i=2; i<maxn; i++)
    14     {
    15         inv[i]=((mod-mod/i)*inv[mod%i]+mod)%mod;
    16     }
    17 }
    18 ll dfs(int u,int type)
    19 {
    20     if(dp[u][type]!=-1)
    21         return dp[u][type];
    22     dp[u][type]=1;
    23     if(type)
    24     {
    25         for(auto i:Edge[u])
    26         {
    27             dp[u][type]=(dp[u][type]+(dfs(i,type^1)+1)*inv[Edge[u].size()]%mod)%mod;
    28         }
    29     }
    30     else
    31     {
    32         for(auto i:Edge[u])
    33         {
    34             dp[u][type]=(dp[u][type]+(dfs(i,type)+1)*inv[Edge[u].size()+1]%mod)%mod;
    35         }
    36         dp[u][type]=(dp[u][type]+(dfs(u,type^1)*inv[Edge[u].size()+1]%mod))%mod;
    37     }
    38     return dp[u][type]%mod;
    39 }
    40 int main()
    41 {
    42     init();
    43     int T;
    44     scanf("%d",&T);
    45     while(T--)
    46     {
    47         int n,m,st,ed;
    48         scanf("%d %d",&n,&m);
    49         for(int i=0;i<=n;i++){Edge[i].clear();}
    50         for(int i=1; i<=m; i++)
    51         {
    52             scanf("%d %d",&st,&ed);
    53             Edge[st].push_back(ed);
    54         }
    55         for(int i=1; i<=n; i++)
    56         {
    57             dp[i][0]=dp[i][1]=-1;
    58         }
    59         ll ans=dfs(1,0);
    60         printf("%lld
    ",ans);
    61     }
    62     return 0;
    63 }
  • 相关阅读:
    【[SDOI2016]排列计数】
    newcoder NOIP提高组模拟赛C题——保护
    【[JLOI2014]松鼠的新家】
    【[USACO08NOV]奶牛混合起来Mixed Up Cows】
    【[USACO13NOV]没有找零No Change】
    【[SHOI2009]会场预约】
    【[USACO12FEB]附近的牛Nearby Cows】
    UVA11987 【Almost Union-Find】
    基于递归的BFS(Level-order)
    遍历二叉树
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10807643.html
Copyright © 2011-2022 走看看