zoukankan      html  css  js  c++  java
  • [高端操作]最值反演

    记 $min{S}$ 为集合 $S$ 中最小值,$max{S}$ 为集合 $S$ 中最大值

    则有 $max{S}=sumlimits_{T subseteq S,T eq emptyset}(-1)^{|T|-1}min{T}$

    这个东西可以用来求“全都出现的期望时间”

    hdu4336 Card Collector

    有 n 种卡片,每秒你有 $P_i$ 的概率获得第 $i$ 张卡片,求获得所有卡片至少一张的期望时间

    $n leq 20$

    sol:

    直接套上面那个式子,令 $max{S}$ 为得到 $S$ 集合中最晚的一张的期望时间,易得这也是得到 $S$ 集合的期望时间

    然后套一下式子,就只用对于 $S$ 的每一个子集 $T$ ,计算出至少得到一个 $T$ 中元素的期望时间

    易得 $min{T}=frac{1}{sumlimits_{i in T}P_i}$

    然后就做完了

    #include<bits/stdc++.h>
    #define LL long long
    using namespace std;
    inline int read()
    {
        int x = 0,f = 1;char ch = getchar();
        for(;!isdigit(ch);ch = getchar())if(ch == '-') f = -f;
        for(;isdigit(ch);ch = getchar())x = 10 * x + ch - '0';
        return x * f;
    }
    int n;double p[25],ans;
    void dfs(int x,double e,int opt)
    {
        if(x > n)
        {
            if(e > 1e-7)ans += opt / e;
            return;
        }
        dfs(x + 1,e,opt);
        dfs(x + 1,e + p[x],-opt);
    }
    int main()
    {
        while(scanf("%d",&n) != EOF)
        {
            for(int i=1;i<=n;i++)cin >> p[i];
            ans = 0;dfs(1,0,-1);
            printf("%.6lf
    ",ans);
        }
    }
    View Code

    PKUWC2018 随机游走

    一棵树,你从 $x$ 出发随机走,$q$ 次询问,每次给定一个点集 $S$,求走完 $S$ 的期望时间

    $n leq 18,q leq 5000$

    sol:

    根据上一题的套路,我们要求对于每个子集 $T$,至少走到 $T$ 中的一个点的期望步数

    然后根据不知道在哪(???)知道的套路,树上期望题可以记 $f_{(x,S)}$ 表示从 $x$ 开始走,第一次走到 $S$ 中的一个元素的期望步数

    考虑这个 $f_{(x,S)}$ 怎么推,如果 $x in S$,则 $f_{(x,S)} = 0$,如果不是的话,$f_{(x,S)} = frac{1}{d_x} imes sum f_{(y,S)} + 1$

    然后发现 $f_{(x,S)}=a_x imes f_{(fa_x,S)} + b_x$ ,从 $0$ 的点向上推出每个 $a,b$ 即可

    #include<bits/stdc++.h>
    #define LL long long
    using namespace std;
    inline int read()
    {
        int x = 0,f = 1;char ch = getchar();
        for(;!isdigit(ch);ch = getchar())if(ch == '-') f = -f;
        for(;isdigit(ch);ch = getchar())x = 10 * x + ch - '0';
        return x * f;
    }
    const int mod = 998244353,maxn = (1 << 20);
    int n,q,x,d[maxn],f[maxn],k[maxn],b[maxn],fa[maxn];
    vector<int> G[30];
    inline int ksm(int x,int t)
    {
        int res = 1;
        while(t)
        {
            if(t & 1) res = 1LL * res * x % mod;
            x = 1LL * x * x % mod;
            t = t >> 1;
        }return res;
    }
    inline void dfs(int x,int S)
    {
        if(S & (1 << (x - 1)))
        {
            k[x] = b[x] = 0;
            return;
        }
        k[x] = b[x] = d[x];
        for(auto to : G[x])
        {
            if(to == fa[x])continue;
            fa[to] = x;dfs(to,S);
            k[x] = (mod - k[to] + k[x]) % mod;
            b[x] = (b[to] + b[x]) % mod;
        }
        k[x] = ksm(k[x],mod - 2);
        b[x] = 1LL * b[x] * k[x] % mod;
    }
    int main()
    {
        n = read();q = read();x = read();
        for(int i=2;i<=n;i++)
        {
            int u = read(),v = read();
            G[u].push_back(v);d[u]++; 
            G[v].push_back(u);d[v]++;
        }
        for(int S=1;S<(1 << n);S++)
        {
            dfs(x,S);
            f[S] = b[x];
        }
        while(q--)
        {
            int nq = read(),S = 0;
            for(int i=1;i<=nq;i++)S = S | (1 << (read() - 1));
            LL ans = 0;
            for(int ps=S;ps;ps=(ps-1)&S)
            {
                int cnt = __builtin_popcount(ps);
                ans = (ans + ((cnt & 1) ? 1 : -1) * f[ps] + mod) % mod;
            }cout<<ans<<endl;
        }
    }
    View Code
  • 相关阅读:
    UIPath RPA 自动化脚本 机器人从入门到精通
    [转]面向物联网的21个开源软件项目
    数字化转型
    区块链项目大全-项目源码链接收藏
    SAP HANA学习资料大全 Simple Finane + Simple Logisitic [非常完善的学习资料汇总]
    今日头条技术架构分析
    巴菲特价值投资的六项法则
    文档大师 2016 :在电脑和头脑中快速找到文档的文件管理软件
    文档大师 在Win10 IE11下,文档集画面无法正常显示Word等Office文档的解决方法
    人脑+电脑:通过文档管理让个人能力大大拓展
  • 原文地址:https://www.cnblogs.com/Kong-Ruo/p/10184329.html
Copyright © 2011-2022 走看看