zoukankan      html  css  js  c++  java
  • loj2538. 「PKUWC2018」Slay the Spire

    题意

    略。

    题解

    考虑到尽可能多选强化卡是更优的,所以如果可以,最后只要选最大的一张攻击即可(除非强化卡不够了)。
    那么按照这个思路,先把两个序列从大到小排序。
    记录(f_{i, j})表示选了(i)张强化卡,其中最后一张是第(j)张的所有方案的强化倍数的和。
    则有

    [f_{i, j} = a_i sum_{k = 1} ^ {j - 1} f_{i - 1, k} ]

    对于攻击卡也类似。
    但这并不是我们想要的。
    我们想要的(F_{i, j})应该是分到(i)张强化卡,(最优地)最后打出了(j)张强化卡的期望强化倍数之和。
    因此,计算(F_{p, q})的式子应该是

    [F_{p, q} = sum_{i = 1} ^ n f_{i, q} inom{n - i}{p - q} ]

    单组复杂度(mathcal O(n ^ 2 + nm))

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N = 3005, mod = 998244353;
    int T, n, m, k, ans;
    int a[N], b[N], s[N], c[N][N], f[N][N], g[N][N];
    void prepare () {
        c[0][0] = 1;
        for (int i = 1; i < N; ++i) {
            c[i][0] = 1;
            for (int j = 1; j <= i; ++j) {
                c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % mod;
            }
        }
    }
    int F (int p, int q) {
        if (p < q) {
            return 0;
        }
        if (!q) {
            return c[n][p];
        }
        int ret = 0;
        for (int i = 1; i <= n; ++i) {
            ret = (1ll * f[q][i] * c[n - i][p - q] + ret) % mod;
        }
        return ret;
    }
    int G (int p, int q) {
        if (p < q) {
            return 0;
        }
        int ret = 0;
        for (int i = 1; i <= n; ++i) {
            ret = (1ll * g[q][i] * c[n - i][p - q] + ret) % mod;
        }
        return ret;
    }
    int main () {
        prepare();
        for (scanf("%d", &T); T; --T) {
            scanf("%d%d%d", &n, &m, &k);
            for (int i = 1; i <= n; ++i) {
                scanf("%d", &a[i]);
            }
            for (int i = 1; i <= n; ++i) {
                scanf("%d", &b[i]);
            }
            sort(a + 1, a + n + 1), reverse(a + 1, a + n + 1);
            sort(b + 1, b + n + 1), reverse(b + 1, b + n + 1);
            for (int i = 1; i <= n; ++i) {
                f[1][i] = a[i];
                s[i] = (s[i - 1] + a[i]) % mod;
            }
            for (int i = 2; i <= n; ++i) {
                for (int j = 1; j <= n; ++j) {
                    f[i][j] = 1ll * a[j] * s[j - 1] % mod;
                }
                for (int j = 1; j <= n; ++j) {
                    s[j] = (s[j - 1] + f[i][j]) % mod;
                }
            }
            for (int i = 1; i <= n; ++i) {
                g[1][i] = b[i];
                s[i] = (s[i - 1] + b[i]) % mod;
            }
            for (int i = 2; i <= n; ++i) {
                for (int j = 1; j <= n; ++j) {
                    g[i][j] = (1ll * b[j] * c[j - 1][i - 1] + s[j - 1] + mod) % mod;
                }
                for (int j = 1; j <= n; ++j) {
                    s[j] = (s[j - 1] + g[i][j]) % mod;
                }
            }
            ans = 0;
            for (int i = 0; i < m; ++i) {
                if (i < k) {
                    ans = (1ll * F(i, i) * G(m - i, k - i) + ans) % mod;
                } else {
                    ans = (1ll * F(i, k - 1) * G(m - i, 1) + ans) % mod;
                }
            }
            printf("%d
    ", ans);
        }
        return 0;
    }
    
  • 相关阅读:
    ElasticSearch实战系列一: ElasticSearch集群+Kinaba安装教程
    SpringBoot事物Transaction实战讲解教程
    SpringBoot整合Swagger和Actuator
    SpringBoot项目实现文件上传和邮件发送
    SpringBoot优雅的全局异常处理
    SpringCloud学习系列之七 ----- Zuul路由网关的过滤器和异常处理
    SpringBoot整合Redis使用Restful风格实现CRUD功能
    SpringCloud学习系列之六 ----- 路由网关Zuul基础使用教程
    SpringCloud学习系列之五-----配置中心(Config)和消息总线(Bus)完美使用版
    SpringCloud学习系列之四-----配置中心(Config)使用详解
  • 原文地址:https://www.cnblogs.com/psimonw/p/11443514.html
Copyright © 2011-2022 走看看