zoukankan      html  css  js  c++  java
  • ABC224 部分题解

    ABC224 部分题解

    E.Integers on Grid

    题意

    给定(R imes C)的矩形,其中(N)个位置有权值(a_{i}) 从当前位置可以移动到当前列或当前行比当前位置权值大的位置

    求这(N)个位置能移动的最大次数

    [2 leq R,C leq 2 imes 10^5\ 1 leq N leq min(2 imes 10^5,RC)\ 1leq a_i leq 10^9 ]

    分析

    对于位置为(i,j)的元素,我们有明显转移方程

    [dp_{i,j} = max(dp_{k,j}) + 1, 1 le k le n,a_{i,j} < a_{k,j}\ dp_{i,j} = max(dp_{i,k}) + 1,1 leq k leq m,a_{i,j} < a_{i,k} ]

    这题用位置转移显然是麻烦的,不妨直接根据权值 从大到小转移,对于每一行维护最大值即可

    代码

    const int maxn = 2e5 + 5;
    
    int r[maxn],c[maxn],a[maxn];
    int rm[maxn],cm[maxn];
    int dp[maxn];
    map<int,VI> mp;
    
    int main(){
        int h = rd();
        int w = rd();
        int n = rd();
        for(int i = 1;i <= n;i++){
            r[i] = rd();
            c[i] = rd();
            a[i] = rd();
            mp[a[i]].push_back(i);
        }
        for(auto it = mp.rbegin();it != mp.rend();it++){
            for(auto i:it -> se) 
                dp[i] = max(rm[r[i]],cm[c[i]]);
            for(auto i:it -> se)
                rm[r[i]] = max(rm[r[i]],dp[i] + 1),cm[c[i]] = max(cm[c[i]],dp[i] + 1);
        }
        for(int i = 1;i <= n;i++)
            printf("%d
    ",dp[i]);
    }
    

    F.Problem where +s Separate Digits

    题意

    给定一个包含1-9的字符串,可以在字符串的非首尾位置随意插入‘+’ ,如1234可以成为12+34,那么这个方案的值为12+34=36

    求所有方案的值的和

    [1 leq |s| leq 2 imes 10^5\ ]

    分析

    考虑每个数的贡献即可,相当于对于一个数钦定其后面几个不能有'+',其余位置随便插入的方案数,这个系数显然是可以转移得出的,于是扫一遍即可

    代码

    const int maxn = 2e5 + 5;
    
    char s[maxn];
    int p2[maxn];
    int p10[maxn];
    
    int main(){
        scanf("%s",s + 1);
        int n = strlen(s + 1);
        p2[0] = 1;
        p10[0] = 1;
        for(int i = 1;i <= n;i++)
            p2[i] = mul(p2[i - 1],2),p10[i] = mul(p10[i - 1],10);
        int ans = 0;
        int sum = 0;
        for(int i = 0;i < n - 1;i++)
            add(sum,mul(p10[i],p2[n - 2 - i]));
        for(int i = 1;i <= n;i++){
            add(ans,mul(s[i] - '0',sum + mul(p10[n - i],p2[i - 1])));
            add(sum,MOD - mul(p10[n - i - 1],p2[n - 1 - (n - i - 1) - 1]));
        }
        cout << ans;
    }
    

    G - Roll or Increment 思维 期望

    题意

    给定(N)个面上分布(1-N)的骰子,初始给定的面是(S),询问最少花费策略下的期望花费使得骰子的面达到(T)

    每次可以进行以下任意两种操作

    • 花费(A)使得当前面所在的值+1(不影响下次)
    • 花费(B)再投一次

    保证每次投的概率分布均匀

    [1 leq N leq 10^9\ 1 leq S,T leq 10^9\ 1 leq A,B leq 10^9 ]

    分析

    显然我们不可能在进行操作1后进行操作2

    所以操作可以归纳为进行若干次操作2后进行若干次操作1

    由于(A)是固定的,我们必然能找到一个阈值(X),使得一旦操作2随机到$geq X $就停止操作2,进行操作1

    期望的花费 = 操作2的花费 + 操作1的花费

    为方便计算令(X = T - X + 1)

    操作2的期望花费 = $Bfrac{1}{P} = Bfrac{N}{X} $

    操作1的期望花费 = (Asum_{i = T - X = 1}^T (T- i ) / X =frac{A(X-1)}{2})

    把花费看作(X)的方程(f (X ) = frac{BN}{X} + frac{A(X-1)}{2})

    它在(X = sqrt{2BN/A}) 时有极值 ,此题再加上一些特判即可

    代码

    inline ld f(int x){
        return (ld)a * (x - 1) / 2 + (ld)b * n / x;
    }
    
    int main(){
        n = rd();
        s = rd();
        t = rd();
        a = rd();
        b = rd();
        ld ans = 1e18;
        if(t >= s) ans = (ld)(t - s) * a;
        int x = sqrt(2. * b * n / a);
        ans = min(ans,f(1));
        ans = min(ans,f(t));
        for(int i = max(0,x - 1);i <= min(t,x + 1);i++)
            ans = min(ans,f(i));
        printf("%.10Lf",ans);
    }
    
  • 相关阅读:
    抽象类和接口的区别
    Overload和Override的区别
    final和finally和finalize的区别
    C#设计模式学习笔记:简单工厂模式(工厂方法模式前奏篇)
    C#设计模式学习笔记:(1)单例模式
    C#设计模式学习笔记:设计原则
    C#加密与解密(DESRSA)学习笔记
    C# IO流与文件读写学习笔记
    C#序列化与反序列化学习笔记
    C#索引器学习笔记
  • 原文地址:https://www.cnblogs.com/hznumqf/p/15477190.html
Copyright © 2011-2022 走看看