The Preliminary Contest for ICPC Asia Nanjing 2019 D. Robots(概率dp)

题目链接:https://nanti.jisuanke.com/t/41301

题目大意:

给定一个没有循环的有向图,它从节点1开始,到节点n结束。

有一个机器人从1开始,每天都会以相同的概率前往相邻节点之一或静止不动。每天机器人的耐久性消耗量等于经过的天数。

请计算机器人到达节点n时的预期耐久性消耗量。

保证只有一个节点(节点1)的in-degree等于00,并且只有一个节点(节点n)的out-degree等于0.并且图中没有多个边缘。

解题思路:

设dp【i】为从i到达终点n的期望时间那么很容易得到:

接下来设ans【i】为从i到达终点的耐久值消耗量,那么状态转移方程为 ans【u】=ans【u】*1(outdeg【u】+1)+1/(outdey【u】+1)*∑ans【v】+dp【u】。由于此图为有向无环图,所以跑边拓扑边转移即可。

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
struct st{
    int to,next;
}stm[maxn*2];
int cnt;
int head[maxn];
void add(int u,int v){
    stm[cnt].to=v;
    stm[cnt].next=head[u];
    head[u]=cnt++;
}
int cd[maxn];
int cd1[maxn];
double dp[maxn];
double ans[maxn];
queue<int> que;
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        int n,m;
        int u,v;
        memset(head,-1,sizeof(head));
        memset(cd,0,sizeof(cd));
        memset(dp,0,sizeof(dp));
        memset(ans,0,sizeof(ans));
        memset(cd1,0,sizeof(cd1));
        cnt=0;
        scanf("%d%d",&n,&m);
        for(int i=0;i<m;i++){
            scanf("%d%d",&u,&v);
            add(v,u);
            cd[u]++;
            cd1[u]++;
        }
        while(!que.empty())que.pop();
        que.push(n);
        while(!que.empty()){
            int now=que.front();
            que.pop();
            for(int i=head[now];~i;i=stm[i].next){
                int to=stm[i].to;
                dp[to]+=1.0/(cd[to]+1)*dp[now];
                ans[to]+=1.0/(cd[to]+1)*ans[now];
            //1.0*(cd[to]+1)/cd[to];
                cd1[to]--;
                if(cd1[to]==0){
                    dp[to]=(dp[to]+1)*1.0*(cd[to]+1)/cd[to];
                    ans[to]=(ans[to]+dp[to])*1.0*(cd[to]+1)/cd[to];
                    que.push(to);
                }
            }
        }
        printf("%.2lf\n",ans[1]);
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/Zhi-71/p/11444076.html

时间: 2024-11-04 01:02:01

The Preliminary Contest for ICPC Asia Nanjing 2019 D. Robots(概率dp)的相关文章

The Preliminary Contest for ICPC Asia Nanjing 2019/2019南京网络赛——题解

(施工中……) 比赛传送门:https://www.jisuanke.com/contest/3004 D. Robots(期望dp) 题意 给一个DAG,保证入度为$0$的点只有$1$,出度为$0$的点只有$n$. 现在一个机器人从$1$出发,每天都会以相同的概率前往相邻节点之一或静止不动. 每天机器人消耗的耐久等于经过的天数. 求机器人到点$n$期望消耗的耐久. 划水划的很愉快,唯一一道做出来的题.但是和题解做法不同(感觉我的方法麻烦),因此砸了3h在这题上面(正在试图读懂题解ing). 设

C:Dawn-K&#39;s water (The Preliminary Contest for ICPC Asia Shenyang 2019)

Dawn-K recently discovered a very magical phenomenon in the supermarket of Northeastern University: The large package is not necessarily more expensive than the small package. On this day, Dawn-K came to the supermarket to buy mineral water, he found

The Preliminary Contest for ICPC Asia Shenyang 2019

The Preliminary Contest for ICPC Asia Shenyang 2019 Texas hold'em Poker #include <bits/stdc++.h> using namespace std; const int maxn=1e6+10; int num[1000]; int shun(){ for (int i=15;i>=5;i--){ if (num[i]&&num[i-1]&&num[i-2]&&a

The Preliminary Contest for ICPC Asia Shanghai 2019 C Triple(FFT+暴力)

The Preliminary Contest for ICPC Asia Shanghai 2019 C Triple(FFT+暴力) 传送门:https://nanti.jisuanke.com/t/41400 题意: 给你三个数组a,b,c,要你求有多少个三元组(i,j,k),使得 \[ \begin{array}{l}{\left|A_{i}-B_{j}\right| \leq C_{k}, \text { and }} \\ {\left|B_{j}-C_{k}\right| \leq

The Preliminary Contest for ICPC Asia Shenyang 2019 H. Texas hold&#39;em Poker

题目链接:https://nanti.jisuanke.com/t/41408 题目意思很简单,就是个模拟过程. 1 #include <iostream> 2 #include <cstring> 3 #include <algorithm> 4 #include <cstdio> 5 #include <map> 6 #define rep(i,j,k) for(int i = (j); i <= (k); ++i) 7 #define

The Preliminary Contest for ICPC Asia Shenyang 2019 F. Honk&#39;s pool

题目链接:https://nanti.jisuanke.com/t/41406 思路:如果k的天数足够大,那么所有水池一定会趋于两种情况: ① 所有水池都是一样的水位,即平均水位 ② 最高水位的水池和最低水位的水池高度只相差一个高度,且最低水位一定是平均水位 如果k给了个限制: 我们当然需要先算出所有水池高度的平均值. 然后从低到高排序,二分小于平均值的水位,二分高于平均值的水位, 然后判断二分的预期值需要的天数是否小于等于k.然后二分找出最低水位的最大值, 最高水位的最小值,两者相减就是答案了

The Preliminary Contest for ICPC Asia Xuzhou 2019

A What is better? 推不出来,写个程序打表,用扩展中国剩余定理合并,居然会溢出longlong,还好不会溢出__int128(赛后exit(-1)测试),实际证明溢出返回-1是不靠谱的,毕竟后面可以又把它搞小了. #include<bits/stdc++.h> using namespace std; typedef long long ll; typedef __int128 lll; const int MAXK = 10 + 5; void exgcd(lll a, ll

The Preliminary Contest for ICPC Asia Shanghai 2019

D. Counting Sequences I 暴力搜索. #include <bits/stdc++.h> using namespace std; typedef long long ll; const int MOD = 1000000007; map<vector<short>, short> m; vector<short> vec; void calc(int num1) { vector<short> tmp; if(num1) t

Digit sum-----The Preliminary Contest for ICPC Asia Shanghai 2019

A digit sum S_b(n)Sb?(n) is a sum of the base-bb digits of nn. Such as S_{10}(233) = 2 + 3 + 3 = 8S10?(233)=2+3+3=8, S_{2}(8)=1 + 0 + 0 = 1S2?(8)=1+0+0=1, S_{2}(7)=1 + 1 + 1 = 3S2?(7)=1+1+1=3. Given NN and bb, you need to calculate \sum_{n=1}^{N} S_b