题目链接

loj2538

题解

比较明显的是,由于强化牌倍数大于\(1\),肯定是能用强化牌尽量用强化牌

如果强化牌大于等于\(k\),就留一个位给攻击牌

所以我们将两种牌分别排序,企图计算\(F(i,j)\)表示\(i\)张强化牌选出最强的\(j\)张的所有方案的倍数和

\(G(i,j)\)表示从\(i\)张攻击牌选出最强\(j\)张的所有方案的伤害和

那么

\[ans = \sum\limits_{i = 0}^{k - 1} F(i,i)G(m - i,k - i) + \sum\limits_{i = k}^{m} F(i,k - 1)G(m - i,1)
\]

所以我们只需计算出\(F\)和\(G\)

以\(F\)为例,我们枚举选出最后一张牌是什么

那么设\(f[i][j]\)表示用了\(i\)张强化牌,最后一张是\(j\)的倍数和

同样设\(g[i][j]\)表示用了\(i\)张攻击牌,最后一张是\(j\)的伤害和

那么有

\[f[i][j] = w_j\sum\limits_{x = 0}^{j - 1}f[i - 1][x]
\]

\[g[i][j] = w_j{j - 1 \choose i - 1} + \sum\limits_{x = 0}^{j - 1}g[i - 1][x]
\]

可用前缀和优化为\(O(n^2)\)

那么

\[F(x,y) = \sum\limits_{i = 0}^{n}f[y][i]{n - i \choose x - y}
\]

\[G(x,y) = \sum\limits_{i = 0}^{n}g[y][i]{n - i \choose x - y}
\]

总复杂度\(O(Tn^2)\)

  1. #include<algorithm>
  2. #include<iostream>
  3. #include<cstring>
  4. #include<cstdio>
  5. #include<cmath>
  6. #include<map>
  7. #define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
  8. #define REP(i,n) for (int i = 1; i <= (n); i++)
  9. #define mp(a,b) make_pair<int,int>(a,b)
  10. #define cls(s) memset(s,0,sizeof(s))
  11. #define cp pair<int,int>
  12. #define LL long long int
  13. using namespace std;
  14. const int maxn = 3005,maxm = 100005,INF = 1000000000,P = 998244353;
  15. inline int read(){
  16. int out = 0,flag = 1; char c = getchar();
  17. while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
  18. while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
  19. return out * flag;
  20. }
  21. int n,m,K,fac[maxn],fv[maxn],inv[maxn];
  22. int w1[maxn],w2[maxn];
  23. int f[maxn][maxn],g[maxn][maxn];
  24. int s[maxn];
  25. void init(){
  26. fac[0] = fac[1] = inv[0] = inv[1] = fv[0] = fv[1] = 1;
  27. for (int i = 2; i <= 3000; i++){
  28. fac[i] = 1ll * fac[i - 1] * i % P;
  29. inv[i] = 1ll * (P - P / i) * inv[P % i] % P;
  30. fv[i] = 1ll * fv[i - 1] * inv[i] % P;
  31. }
  32. }
  33. inline int C(int n,int m){
  34. if (n < m) return 0;
  35. return 1ll * fac[n] * fv[m] % P * fv[n - m] % P;
  36. }
  37. inline int F(int x,int y){
  38. if (x > n || x < y) return 0;
  39. int re = 0;
  40. for (int i = 0; i <= n; i++)
  41. re = (re + 1ll * f[y][i] * C(n - i,x - y) % P) % P;
  42. return re;
  43. }
  44. inline int G(int x,int y){
  45. if (x > n || x < y) return 0;
  46. int re = 0;
  47. for (int i = 0; i <= n; i++)
  48. re = (re + 1ll * g[y][i] * C(n - i,x - y) % P) % P;
  49. return re;
  50. }
  51. inline bool cmp(const int& a,const int& b){
  52. return a > b;
  53. }
  54. void work(){
  55. sort(w1 + 1,w1 + 1 + n,cmp);
  56. sort(w2 + 1,w2 + 1 + n,cmp);
  57. for (int i = 0; i <= n; i++)
  58. for (int j = 0; j <= n; j++)
  59. f[i][j] = g[i][j] = 0;
  60. f[0][0] = 1;
  61. s[0] = 1;
  62. for (int i = 1; i <= n; i++) s[i] = s[i - 1];
  63. for (int i = 1; i <= n; i++){
  64. for (int j = i; j <= n; j++){
  65. f[i][j] = 1ll * w1[j] * s[j - 1] % P;
  66. }
  67. for (int j = 0; j < i; j++) s[j] = 0;
  68. for (int j = i; j <= n; j++) s[j] = (s[j - 1] + f[i][j]) % P;
  69. }
  70. s[0] = 0;
  71. for (int i = 1; i <= n; i++) s[i] = s[i - 1];
  72. for (int i = 1; i <= n; i++){
  73. for (int j = i; j <= n; j++){
  74. g[i][j] = (1ll * w2[j] * C(j - 1,i - 1) % P + s[j - 1]) % P;
  75. }
  76. for (int j = 0; j < i; j++) s[j] = 0;
  77. for (int j = i; j <= n; j++) s[j] = (s[j - 1] + g[i][j]) % P;
  78. }
  79. int ans = 0;
  80. for (int i = 0; i <= min(n,m); i++){
  81. int j = m - i; if (j < 0 || j > n) continue;
  82. if (i < K){
  83. ans = (ans + 1ll * F(i,i) * G(j,K - i) % P) % P;
  84. }
  85. else{
  86. ans = (ans + 1ll * F(i,K - 1) * G(j,1) % P) % P;
  87. }
  88. }
  89. printf("%d\n",ans);
  90. }
  91. int main(){
  92. init();
  93. int T = read();
  94. while (T--){
  95. n = read(); m = read(); K = read();
  96. REP(i,n) w1[i] = read();
  97. REP(i,n) w2[i] = read();
  98. work();
  99. }
  100. return 0;
  101. }

loj2538 「PKUWC2018」Slay the Spire 【dp】的更多相关文章

  1. LOJ2538. 「PKUWC2018」Slay the Spire【组合数学】

    LINK 思路 首先因为式子后面把方案数乘上了 所以其实只用输出所有方案的攻击力总和 然后很显然可以用强化牌就尽量用 因为每次强化至少把下面的牌翻一倍,肯定是更优的 然后就只有两种情况 强化牌数量少于 ...

  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. loj2542 「PKUWC2018」随机游走 【树形dp + 状压dp + 数学】

    题目链接 loj2542 题解 设\(f[i][S]\)表示从\(i\)节点出发,走完\(S\)集合中的点的期望步数 记\(de[i]\)为\(i\)的度数,\(E\)为边集,我们很容易写出状态转移方 ...

  7. LOJ2542. 「PKUWC2018」随机游走【概率期望DP+Min-Max容斥(最值反演)】

    题面 思路 我们可以把到每个点的期望步数算出来取max?但是直接算显然是不行的 那就可以用Min-Max来容斥一下 设\(g_{s}\)是从x到s中任意一个点的最小步数 设\(f_{s}\)是从x到s ...

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

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

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

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

随机推荐

  1. oracle 数据库的详细安装教程

    由于oracle数据库比较大 所以安装的时候比较慢是目前装的最大的软件了吧 而且如果装崩了 可能还会重装系统 不过比较幸运 一次就装好 1.需要去官网下载  https://www.oracle.co ...

  2. 零基础学Python之结构化数据(附详细的代码解释和执行结果截图)

    3结构化数据 字典(查找表).集合.元组.列表 3.1字典 是有两列任意多行的表,第一列存储一个键,第二列存储一个值. 它存储键/值对,每个唯一的键有一个唯一与之关联的值.(类似于映射.表) 它不会维 ...

  3. java基础---类加载和对象创建过程

    类中可以存在的成员: class A{ 静态成员变量: 非静态成员变量: 静态函数: 非静态函数: 构造函数 A(..){...} 静态代码块 static{...} 构造代码块 {...} } 类加 ...

  4. 基于Python的信用评分卡模型分析(二)

    上一篇文章基于Python的信用评分卡模型分析(一)已经介绍了信用评分卡模型的数据预处理.探索性数据分析.变量分箱和变量选择等.接下来我们将继续讨论信用评分卡的模型实现和分析,信用评分的方法和自动评分 ...

  5. 基于C#的机器学习--贝叶斯定理-执行数据分析解决肇事逃逸之谜

    贝叶斯定理-执行数据分析解决肇事逃逸之谜 ​ 在这一章中,我们将: 应用著名的贝叶斯定理来解决计算机科学中的一个非常著名的问题. 向您展示如何使用贝叶斯定理和朴素贝叶斯来绘制数据,从真值表中发现异常值 ...

  6. ifconfig命令详情

    基础命令学习目录首页 原文链接:https://blog.csdn.net/weixin_37886382/article/details/79716879 许多windows非常熟悉ipconfig ...

  7. Scrum立会报告+燃尽图(Final阶段第一次)

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2480 项目地址:https://coding.net/u/wuyy694 ...

  8. sprint会议1

    昨天:进行第一次站立会议,讨论冲刺阶段,目标,任务认领,制作索引卡. 今天:准备查找安卓APP开发的有关资料,安装有关软件. 遇到的问题:对这方面毫无了解,不知道怎么开始,从哪开始,完全没经验.

  9. HDU 4745 Two Rabbits 区间dp_回文序列

    题目链接: http://blog.csdn.net/scnu_jiechao/article/details/11759333 Two Rabbits Time Limit: 10000/5000 ...

  10. 第三次作业---excel导入数据库及显示

    好吧首先承认这次作业失败了,而且我并不知道原因.另外,我也没有采用PowerDesigner 设计所需要的数据库,代码就用了全部的时间.感觉自己就像一个刚学会爬着走路的小孩去参加一百一十米跨栏,能不能 ...