首页 > 其他分享 >GYM 101147K Touristic Trip

GYM 101147K Touristic Trip

时间:2023-05-04 20:13:32浏览次数:61  
标签:明信片 int GYM ++ 101147K dpB dpAB Trip dp

首先可以看出这是一个条件概率 \(P(A/B) = \frac{P(AB)}{P(B)}\),其中 \(A\) 事件为“满足在 \(Z\) 城市时寄出第 \(Q\) 张明信片”,\(B\) 事件为“满足得到的明信片序列与给出的明信片序列相同”
那只需要求出 \(P(AB)\) 和 \(P(B)\) 就能得到最终答案了

首先考虑 \(B\) 事件
发现这些要求都只与现在该寄出的明信片数和现在所在的城市有关,明信片序列是固定的,所以设 \(dp_{i, j}\) 为现在该寄出第 \(i\) 张明信片且现在在 \(j\) 城市满足 \(B\) 事件的概率
发现这个状态只可能由寄出上一张明信片时的任一城市的状态走来,即 \(dp_{i - 1, h}\) 推来,同时要乘上对应走过来的概率 \(P_{h, j}\),但是还没有满足 \(B\) 事件,因为此时不能确保选到的明信片,所以再乘上 \(C_{j, a_i}\),式子如下:
\(dp_{i, j} = C_{j, a_i}\sum\limits_{h = 0}^{n - 1} dp_{i - 1, h}\times dp_{h, j}\)

考虑 \(AB\) 事件该怎么做,发现其就是在 \(B\) 事件上多了个 \(A\) 事件的限制,直接沿用 \(B\) 事件的 \(\text{DP}\)
发现 \(A\) 事件的限制“该寄出第 \(Q\) 张明信片时只能通过 \(Z\) 城市”可以转化成“该寄出第 \(Q\) 张明信片时不能通过除 \(Z\) 的点”,那就挺好办了:
\(dp_{q, j} = 0\quad (j\not= Z)\)
其他的没有约束正常跑就行了

时间复杂度 \(O(kn^2)\)

无注释版本

#include<bits/stdc++.h>
using namespace std;
const int N = 20 + 2, M = 10 + 2, K = 15 + 2;
int n, m; int k, q, z;
double P[N][N], C[N][M]; int a[N];
double dpAB[K][N], dpB[K][N];
void solve() {
    scanf("%d%d%d%d%d", &n, &m, &k, &q, &z);
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            scanf("%lf", &P[i][j]);
        }
    }
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            scanf("%lf", &C[i][j]);
        }
    }
    for (int i = 0; i < k; i++) {
        scanf("%d", &a[i]);
    }
    memset(dpAB, 0, sizeof(dpAB)), memset(dpB, 0, sizeof(dpB));
    dpAB[0][0] = (q == 0 && z != 0 ? 0 : C[0][a[0]]), dpB[0][0] = C[0][a[0]];
    // 注意判断当初始在 0 时就不能走的情况
    for (int i = 1; i < k; i++) {
        for (int j = 0; j < n; j++) {
            for (int h = 0; h < n; h++) {
                dpB[i][j] += dpB[i - 1][h] * P[h][j], dpAB[i][j] += dpAB[i - 1][h] * P[h][j];
            }
            dpB[i][j] *= C[j][a[i]], dpAB[i][j] *= C[j][a[i]];
            if (i == q && j != z) {
                dpAB[i][j] = 0;
                // 此时不能经过这个点
            }
        }
    }
    double ansAB = 0.0, ansB = 0.0;
    for (int i = 0; i < n; i++) {
        ansAB += dpAB[k - 1][i], ansB += dpB[k - 1][i];
    }
    printf("%.3lf\n", ansAB / ansB);
    // 条件概率
    return ;
}
int main() {
    freopen("trip.in", "r", stdin);
    int testcase;
    scanf("%d", &testcase);
    for (; testcase; testcase--) {
        solve();
    }
    return 0;
}

标签:明信片,int,GYM,++,101147K,dpB,dpAB,Trip,dp
From: https://www.cnblogs.com/lhzawa/p/17372355.html

相关文章

  • Codeforces Gym 103439D - LIS Counting(猜结论+状压)
    一道需要一些猜结论技巧的中档题。首先突破口在于排列长度恰好等于不是额外输入的某个数\(k\)而是LDS与LIS的乘积,这显然启示我们去找一些性质。根据dilworth定理,最长反链等于最小链覆盖,故LIS的长度,就是最少需要的递减数列的个数使得每个元素被覆盖至少一次,而每个递减数......
  • ICS TRIPLEX工业备件T9481 T9451
    W;① ⑧ 0 ③ 0 ① 7 ⑦ ⑦ 5 ⑨   ICSTRIPLEX工业备件T9481T9451T9432T9431T9431T9402T9310-02PN-175486T9110T8800T8480CT8461CT8461T8431T8403CXT8403CT8312-4T8311T8310T8300T8231T8193T8191T8160T8151BT810091001.1四......
  • G2 - Magic Triples (Hard Version)
    题解:值域分治,降低时间复杂度到n*1000+map代码1:点击查看代码#include<bits/stdc++.h>usingnamespacestd;typedeflonglongLL;typedefpair<int,int>PLL;#defineIOScin.tie(nullptr)->sync_with_stdio(false);#definesesecond#definefifirst#definemem(a,b)......
  • CF1822G2 - Magic Triples
    比较好的题目,别的不说,G1对G2有着不错的启发性。首先,因为\(b>0,a_k\le10^9\),所以\(b\)不可能超过\(\sqrt{a}\)考虑对\(b\)分类讨论,设置一个阈值\(B\),先处理\(b=1\)的情况,其实就是取三个相同的数然后排列,可以比较简单的排序之后做到\(O(n)\)。接着手写一个哈希表用......
  • ICS TRIPLEX T8461
    W;① ⑧ 0  ③0 ① ⑦  77 ⑤  ⑨ICSTRIPLEXT8461T8403WoodwardDSLC-2™(数字同步器和负载控制)是一种基于微处理器的同步器和负载控制,设计用于三相交流发电机。DSLC-2将同步器、负载传感器、负载控制、死母线闭合系统、VAR、功率因数和过程控制组合在一......
  • ICS TRIPLEX 工业模块 T8403
    W;1 ⑧ 0 ③0① ⑦ 7 7⑤9ICSTRIPLEX工业模块T8403 TC-505-02-4M5 发电系统的发电机组控制伍德沃德为发电机组市场提供范围广泛的控制器。我们努力降低总安装/运营成本和调试时间,同时提高可用性、效率、可靠性和寿命。T8403 T8403 T8461 T8461C T8403 ......
  • C# 设置Menustrip提示框的显示 -转载
    设置Menustrip提示框的显示:(1)先在Menustrip的属性中对【ShowItemToolTips】的属性进行设置,设置为true代表要显示提示框,如下图设置: (2)设置ToolStripMenuItem的【AutoToolTip】属性,设置为true代表要显示提示框,如下图设置: (3)设置ToolStripMenuItem的【ToolTipText】属性,设置提示......
  • GYM104081 部分题解
    比赛链接:https://codeforces.com/gym/104081目前就做了8题,里面还有4个水题……水题:ACEG,模拟题意即可,C和E有一些细节。不想写题解了F首先目标是如何将这9个数分组,由于答案一定存在,考虑随机化,固定\(a_1\inS_1\),然后随机一个\(a_i\inS_1\),异或得到\(S_1\)的另一......
  • papamelon 302. 碰撞游戏 Stripies(挑战程序设计竞赛)
    地址https://www.papamelon.com/problem/302http://poj.org/problem?id=1862解答自取了几个样例从大到小和从小到大进行模拟发现最大的数最先碰撞则开方的次数最多,所以需要结果最小,则优先去最大的数进行合并。代码如下#include<iostream>#include<algorithm>#includ......
  • Codeforces Gym 103931F - Forest of Magic(时间轴分块+线段树合并)
    一个巨烦的时间轴分块做法,有点类似于P2137Gty的妹子树先考虑静态的情况。看上去就一脸线段树合并对吧?一次修改的操作对一个点\(x\)贡献可以写成\(k·dep_x+b\)的形式,开两棵线段树合并维护一次项和零次项系数即可。由于静态问题可做,因此考虑时间轴分块。设阈值\(B\),每\(B......