loj2538 「PKUWC2018」Slay the Spire 【dp】
题目链接
题解
比较明显的是,由于强化牌倍数大于\(1\),肯定是能用强化牌尽量用强化牌
如果强化牌大于等于\(k\),就留一个位给攻击牌
所以我们将两种牌分别排序,企图计算\(F(i,j)\)表示\(i\)张强化牌选出最强的\(j\)张的所有方案的倍数和
\(G(i,j)\)表示从\(i\)张攻击牌选出最强\(j\)张的所有方案的伤害和
那么
\]
所以我们只需计算出\(F\)和\(G\)
以\(F\)为例,我们枚举选出最后一张牌是什么
那么设\(f[i][j]\)表示用了\(i\)张强化牌,最后一张是\(j\)的倍数和
同样设\(g[i][j]\)表示用了\(i\)张攻击牌,最后一张是\(j\)的伤害和
那么有
\]
\]
可用前缀和优化为\(O(n^2)\)
那么
\]
\]
总复杂度\(O(Tn^2)\)
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<map>
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define mp(a,b) make_pair<int,int>(a,b)
#define cls(s) memset(s,0,sizeof(s))
#define cp pair<int,int>
#define LL long long int
using namespace std;
const int maxn = 3005,maxm = 100005,INF = 1000000000,P = 998244353;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
return out * flag;
}
int n,m,K,fac[maxn],fv[maxn],inv[maxn];
int w1[maxn],w2[maxn];
int f[maxn][maxn],g[maxn][maxn];
int s[maxn];
void init(){
fac[0] = fac[1] = inv[0] = inv[1] = fv[0] = fv[1] = 1;
for (int i = 2; i <= 3000; i++){
fac[i] = 1ll * fac[i - 1] * i % P;
inv[i] = 1ll * (P - P / i) * inv[P % i] % P;
fv[i] = 1ll * fv[i - 1] * inv[i] % P;
}
}
inline int C(int n,int m){
if (n < m) return 0;
return 1ll * fac[n] * fv[m] % P * fv[n - m] % P;
}
inline int F(int x,int y){
if (x > n || x < y) return 0;
int re = 0;
for (int i = 0; i <= n; i++)
re = (re + 1ll * f[y][i] * C(n - i,x - y) % P) % P;
return re;
}
inline int G(int x,int y){
if (x > n || x < y) return 0;
int re = 0;
for (int i = 0; i <= n; i++)
re = (re + 1ll * g[y][i] * C(n - i,x - y) % P) % P;
return re;
}
inline bool cmp(const int& a,const int& b){
return a > b;
}
void work(){
sort(w1 + 1,w1 + 1 + n,cmp);
sort(w2 + 1,w2 + 1 + n,cmp);
for (int i = 0; i <= n; i++)
for (int j = 0; j <= n; j++)
f[i][j] = g[i][j] = 0;
f[0][0] = 1;
s[0] = 1;
for (int i = 1; i <= n; i++) s[i] = s[i - 1];
for (int i = 1; i <= n; i++){
for (int j = i; j <= n; j++){
f[i][j] = 1ll * w1[j] * s[j - 1] % P;
}
for (int j = 0; j < i; j++) s[j] = 0;
for (int j = i; j <= n; j++) s[j] = (s[j - 1] + f[i][j]) % P;
}
s[0] = 0;
for (int i = 1; i <= n; i++) s[i] = s[i - 1];
for (int i = 1; i <= n; i++){
for (int j = i; j <= n; j++){
g[i][j] = (1ll * w2[j] * C(j - 1,i - 1) % P + s[j - 1]) % P;
}
for (int j = 0; j < i; j++) s[j] = 0;
for (int j = i; j <= n; j++) s[j] = (s[j - 1] + g[i][j]) % P;
}
int ans = 0;
for (int i = 0; i <= min(n,m); i++){
int j = m - i; if (j < 0 || j > n) continue;
if (i < K){
ans = (ans + 1ll * F(i,i) * G(j,K - i) % P) % P;
}
else{
ans = (ans + 1ll * F(i,K - 1) * G(j,1) % P) % P;
}
}
printf("%d\n",ans);
}
int main(){
init();
int T = read();
while (T--){
n = read(); m = read(); K = read();
REP(i,n) w1[i] = read();
REP(i,n) w2[i] = read();
work();
}
return 0;
}
loj2538 「PKUWC2018」Slay the Spire 【dp】的更多相关文章
- LOJ2538. 「PKUWC2018」Slay the Spire【组合数学】
LINK 思路 首先因为式子后面把方案数乘上了 所以其实只用输出所有方案的攻击力总和 然后很显然可以用强化牌就尽量用 因为每次强化至少把下面的牌翻一倍,肯定是更优的 然后就只有两种情况 强化牌数量少于 ...
- loj #2538. 「PKUWC2018」Slay the Spire
$ \color{#0066ff}{ 题目描述 }$ 九条可怜在玩一个很好玩的策略游戏:Slay the Spire,一开始九条可怜的卡组里有 \(2n\) 张牌,每张牌上都写着一个数字\(w_i\) ...
- 【LOJ】#2538. 「PKUWC2018」Slay the Spire
题解 由于强化卡都是大于1的,我们分析一下就会发现,尽可能多的用强化卡,至少用一张攻击卡,一定是每组卡牌的最优选择 所以我们把攻击卡和强化卡从大到小排序 我们设\(g[i][j]\)表示前i张卡牌里选 ...
- 「PKUWC2018」Slay the Spire
题目链接 题意分析 这个题其实不是期望 就是一共有\(C_{2n}^m\)种情况 每一种情况选择\(k\)张牌 然后求最大攻击值的总和 我们考虑 当前抽出了选出了\(i\)张强化牌 \(m-i\)张攻 ...
- LOJ #2538. 「PKUWC 2018」Slay the Spire (期望dp)
Update on 1.5 学了 zhou888 的写法,真是又短又快. 并且空间是 \(O(n)\) 的,速度十分优秀. 题意 LOJ #2538. 「PKUWC 2018」Slay the Spi ...
- loj2542 「PKUWC2018」随机游走 【树形dp + 状压dp + 数学】
题目链接 loj2542 题解 设\(f[i][S]\)表示从\(i\)节点出发,走完\(S\)集合中的点的期望步数 记\(de[i]\)为\(i\)的度数,\(E\)为边集,我们很容易写出状态转移方 ...
- LOJ2542. 「PKUWC2018」随机游走【概率期望DP+Min-Max容斥(最值反演)】
题面 思路 我们可以把到每个点的期望步数算出来取max?但是直接算显然是不行的 那就可以用Min-Max来容斥一下 设\(g_{s}\)是从x到s中任意一个点的最小步数 设\(f_{s}\)是从x到s ...
- Loj #2542. 「PKUWC2018」随机游走
Loj #2542. 「PKUWC2018」随机游走 题目描述 给定一棵 \(n\) 个结点的树,你从点 \(x\) 出发,每次等概率随机选择一条与所在点相邻的边走过去. 有 \(Q\) 次询问,每次 ...
- 「PKUWC2018」随机游走(min-max容斥+FWT)
「PKUWC2018」随机游走(min-max容斥+FWT) 以后题目都换成这种「」形式啦,我觉得好看. 做过重返现世的应该看到就想到 \(min-max\) 容斥了吧. 没错,我是先学扩展形式再学特 ...
随机推荐
- Hyperledger Fabric CA User’s Guide——开始(三)
Fabric CA User’s Guide——开始 先决条件 安装Go 1.9+ 设置正确的GOPATH环境变量 安装了libtool和libtdhl-dev包 下面是在Ubuntu上安装libto ...
- [2017 ACL] 对话系统
Long Papers [Domain adaptation ] 1. Adversarial Adaptation of Synthetic or Stale Data ( Cited by 14 ...
- XSS构造技巧
利用字符编码: 百度曾经出过一个XSS漏洞,在一个<script>标签中输出一个变量,其中转义了双引号: var redirectUrl="\";alert(/XSS/ ...
- [机器学习]-K近邻-最简单的入门实战例子
本篇文章分为两个部分,前一部分主要简单介绍K近邻,后一部分是一个例子 第一部分--K近邻简介 从字面意思就可以容易看出,所谓的K近邻,就是找到某个样本距离(这里的距离可以是欧式距离,曼哈顿距离,切比雪 ...
- [leetcode-921-Minimum Add to Make Parentheses Valid]
Given a string S of '(' and ')' parentheses, we add the minimum number of parentheses ( '(' or ')', ...
- TeamWork#3,Week5,Scrum Meeting 11.13
最近我们根据之前发现的问题, 补充了相关知识,正在努力修复出现的问题,调整程序结构. 成员 已完成 待完成 彭林江 之前没有考虑到网站信息更新导致的程序可变性,正在调整爬虫程序结构 更换爬虫结构 郝倩 ...
- Alpha版本测试文档
概述 本次测试主要是为了测试是否有导致崩溃的bug,验证是否符合软件基本需求. 测试环境 硬件测试:安卓系统手机,安卓平板. 测试人员 赖彦谕,金哉仁. 实际进度 2015/11/6 – 2015/1 ...
- 第二阶段Sprint冲刺会议7
进展:试着把视频录制功能加到时间提醒中,但是整合没有成功,今天没有进展.
- fragment的学习
这个讲的不错 http://blog.csdn.net/lmj623565791/article/details/37992017 Fragment与Activity交互的几种方式(二,使用Bund ...
- lintcode-513-完美平方
513-完美平方 给一个正整数 n, 找到若干个完全平方数(比如1, 4, 9, ... )使得他们的和等于 n.你需要让平方数的个数最少. 样例 给出 n = 12, 返回 3 因为 12 = 4 ...