LINK


思路

首先因为式子后面把方案数乘上了

所以其实只用输出所有方案的攻击力总和

然后很显然可以用强化牌就尽量用

因为每次强化至少把下面的牌翻一倍,肯定是更优的

然后就只有两种情况

  • 强化牌数量少于k
  • 强化牌数量大于等于k

根据乘法原理,设\(f_{i,j}\)是选i张强化牌用j张的倍数总和,\(g_{i,j}\)是选i张攻击用j张的倍数总和

\(ans+=f_{k,k}*g_{m-i,m-k}\)

\(ans+=f_{i,k-1}*g_{m-i,1}\)

然后f的计算可以量化大小这个东西,就是先排序

dp出选了i个数,最后一个在j的方案数,这样前面的j各种不可能选出其他数,对于后面的数直接组合数计算就可以了


#include<bits/stdc++.h>

using namespace std;

const int Mod = 998244353;

const int N = 3e3 + 10;

int n, m, k, a[N], b[N], c[N][N];
int sum[N], f[N][N], g[N][N]; int add(int a, int b) {
return (a += b) >= Mod ? a - Mod : a;
} int mul(int a, int b) {
return 1ll * a * b % Mod;
} void init() {
for (int i = 0; i < N; i++) c[i][0] = 1;
for (int i = 1; i < N; i++) {
for (int j = 1; j <= i; j++) {
c[i][j] = add(c[i - 1][j], c[i - 1][j - 1]);
}
}
} int calcf(int a, int b) { // 取a张用b张
if (a < b) return 0;
if (!b) return c[n][a]; //**
int res = 0;
for (int i = 1; i <= n; i++)
res = add(res, mul(f[b][i], c[n - i][a - b]));
return res;
} int calcg(int a, int b) {
if (a < b) return 0;
if (!b) return 0; //**
int res = 0;
for (int i = 1; i <= n; i++)
res = add(res, mul(g[b][i], c[n - i][a - b]));
return res;
} void solve() {
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, [&](const int a, const int b) {return a > b;});
sort(b + 1, b + n + 1, [&](const int a, const int b) {return a > b;});
for (int i = 1; i <= n; i++) {
f[1][i] = a[i];
sum[i] = add(sum[i - 1], a[i]);
}
for (int i = 2; i <= n; i++) {
for (int j = i; j <= n; j++)
f[i][j] = mul(sum[j - 1], a[j]);
for (int j = 1; j <= n; j++)
sum[j] = add(sum[j - 1], f[i][j]);
}
for (int i = 1; i <= n; i++) {
g[1][i] = b[i];
sum[i] = add(sum[i - 1], b[i]);
}
for (int i = 2; i <= n; i++) {
for (int j = i; j <= n; j++) {
g[i][j] = add(mul(b[j], c[j - 1][i - 1]), sum[j - 1]);
}
for (int j = 1; j <= n; j++)
sum[j] = add(sum[j - 1], g[i][j]);
}
int ans = 0;
for (int i = max(0, m - n); i <= min(n, m); i++) {
if (i < k) ans = add(ans, mul(calcf(i, i), calcg(m - i, k - i)));
else ans = add(ans, mul(calcf(i, k - 1), calcg(m - i, 1)));
}
printf("%d\n", ans);
} int main() {
#ifdef dream_maker
freopen("input.txt", "r", stdin);
#endif
init();
int T; scanf("%d", &T);
while (T--) solve();
return 0;
}

LOJ2538. 「PKUWC2018」Slay the Spire【组合数学】的更多相关文章

  1. loj2538 「PKUWC2018」Slay the Spire 【dp】

    题目链接 loj2538 题解 比较明显的是,由于强化牌倍数大于\(1\),肯定是能用强化牌尽量用强化牌 如果强化牌大于等于\(k\),就留一个位给攻击牌 所以我们将两种牌分别排序,企图计算\(F(i ...

  2. loj #2538. 「PKUWC2018」Slay the Spire

    $ \color{#0066ff}{ 题目描述 }$ 九条可怜在玩一个很好玩的策略游戏:Slay the Spire,一开始九条可怜的卡组里有 \(2n\) 张牌,每张牌上都写着一个数字\(w_i\) ...

  3. 【LOJ】#2538. 「PKUWC2018」Slay the Spire

    题解 由于强化卡都是大于1的,我们分析一下就会发现,尽可能多的用强化卡,至少用一张攻击卡,一定是每组卡牌的最优选择 所以我们把攻击卡和强化卡从大到小排序 我们设\(g[i][j]\)表示前i张卡牌里选 ...

  4. 「PKUWC2018」Slay the Spire

    题目链接 题意分析 这个题其实不是期望 就是一共有\(C_{2n}^m\)种情况 每一种情况选择\(k\)张牌 然后求最大攻击值的总和 我们考虑 当前抽出了选出了\(i\)张强化牌 \(m-i\)张攻 ...

  5. LOJ #2538. 「PKUWC 2018」Slay the Spire (期望dp)

    Update on 1.5 学了 zhou888 的写法,真是又短又快. 并且空间是 \(O(n)\) 的,速度十分优秀. 题意 LOJ #2538. 「PKUWC 2018」Slay the Spi ...

  6. Loj #2542. 「PKUWC2018」随机游走

    Loj #2542. 「PKUWC2018」随机游走 题目描述 给定一棵 \(n\) 个结点的树,你从点 \(x\) 出发,每次等概率随机选择一条与所在点相邻的边走过去. 有 \(Q\) 次询问,每次 ...

  7. 「PKUWC2018」随机游走(min-max容斥+FWT)

    「PKUWC2018」随机游走(min-max容斥+FWT) 以后题目都换成这种「」形式啦,我觉得好看. 做过重返现世的应该看到就想到 \(min-max\) 容斥了吧. 没错,我是先学扩展形式再学特 ...

  8. 「PKUWC2018」猎人杀

    「PKUWC2018」猎人杀 解题思路 首先有一个很妙的结论是问题可以转化为已经死掉的猎人继续算在概率里面,每一轮一直开枪直到射死一个之前没死的猎人为止. 证明,设所有猎人的概率之和为 \(W\) , ...

  9. loj#2537. 「PKUWC2018」Minimax

    题目链接 loj#2537. 「PKUWC2018」Minimax 题解 设\(f_{u,i}\)表示选取i的概率,l为u的左子节点,r为u的子节点 $f_{u,i} = f_{l,i}(p \sum ...

随机推荐

  1. 音视频学习系列第(五)篇---MediaRecorder的使用

    音视频系列 什么是MediaRecorder MediaRecorder是安卓提供的一个用于音视频采集的类 在前几篇文章中,我们已经介绍了如何进行音频和视频的采集,即通过AudioRecord采集音频 ...

  2. idea运行main方法报错,提示Shorten command line for xxx

    在Intell IDEA运行main函数的时候遇到了如下错误: Error running' xxxxxx': Command line is too long. Shorten command li ...

  3. rxjs学习

    推荐一个好的网站:http://cn.rx.js.org/manual/overview.html#- https://rxjs-cn.github.io/learn-rxjs-operators/o ...

  4. 通过IIS寄宿WCF服务

    WCF全面解析一书中的例子S104,直接将Service目录部署到iis是无法得到服务相应的,需要在项目中新建一个web项目,删除掉自动生成的所有文件之后,把Service目录下的Calculator ...

  5. LeetCode--204--计数质数

    问题描述: 统计所有小于非负整数 n 的质数的数量. 示例: 输入: 10 输出: 4 解释: 小于 10 的质数一共有 4 个, 它们是 2, 3, 5, 7 . 方法1:经典的判断是否为质数遍历( ...

  6. Bash and a Tough Math Puzzle CodeForces - 914D (线段树二分)

    大意:给定序列, 单点修改, 区间询问$[l,r]$内修改至多一个数后$gcd$能否为$x$ 这题比较有意思了, 要注意到询问等价于$[l,r]$内最多有1个数不为$x$的倍数 可以用线段树维护gcd ...

  7. 解决导入Gradle项目遇到的问题

    Gradle安装好了,插件也在eclipse中配置好了,却不会导入,尴尬.这里我就给大家介绍几个在配置 导入项目所遇到的问题: 分别选择Browse选中本地目录,和BuildModel创建相关的项目文 ...

  8. git 添加tag

    前言 什么是tag?tag是节点的意思,一般在上线的时候使用.比如说:你在本地做了好几个功能,然后把这些功能提交到了上线的分支上,某个时刻,你想上线你的新功能,这个时候你需要你个tag来标记一下,告诉 ...

  9. OAF中下载附件之后页面失效,报过时的数据异常,浏览器后退异常

    我在使用了下载功能之后,再往页面添加行或进行保存,页面老是报浏览器后退的异常. 猜测是因为我的下载按钮使用的submitButton,它隐式的包含了一个submit动作,且我在代码中有一个Commit ...

  10. Python中变量、赋值、浅拷贝、深拷贝

    https://www.cnblogs.com/LetMe/p/6724555.html 在理解浅拷贝和深拷贝之前,首先要理解学习一下变量在Python中是怎样存储的: 变量的类型是分值引用与地址引用 ...