LOJ2538 PKUWC2018 Slay the Spire DP
不想放题面了,咕咕咕咕咕
这个期望明明是用来吓人的,其实要算的就是所有方案的最多伤害的和。
首先可以知道的是,能出强化牌就出强化牌(当然最后要留一张攻击牌出出去),且数字尽量大
所以说在强化牌数量$< K$时会打出所有强化牌和剩下的最大的攻击牌,而强化牌数量$\geq K$的时候则会打出$K-1$张强化牌和$1$张攻击牌,且它们的数字都是最大的
我们不妨计算每一种最优打出的方案存在在多少种抽取方案中。
设$f_{i,j}$表示使用$i$张强化牌,其中数值最小的牌是第$j$张时的方案的强化数值之和,$g_{i,j}$表示使用$i$张攻击牌,其中数值最小的牌是第$j$张时的方案的攻击数值之和,简单的前缀和优化DP就可以完成。处理完之后,所有抽取了$x$张强化牌和$y$张攻击牌,选择$i$张强化牌和$j$张攻击牌的方案的总伤害和就是
$$\sum\limits_k \sum\limits_l f_{i,k} \times g_{j,l} \times C_{k-1}^{x-i} \times C_{l-1}^{y-j}$$
两个理解:
①$f$和$g$中间用乘号是因为$f$中间的每一个方案和$g$中的每一个方案都可以对应产生一种抽取方式
②后面的两个组合数的意思是:对于强化牌,已经使用了$i$张,最小的是$k$,那么剩下的$x-i$张需要在剩余的$k-1$中抽取,方案数就是组合数,后面同理
那么我们枚举强化牌抽了多少张,就可以直接计算答案。
#include<bits/stdc++.h>
//This code is written by Itst
using namespace std; inline int read(){
int a = ;
bool f = ;
char c = getchar();
while(c != EOF && !isdigit(c)){
if(c == '-')
f = ;
c = getchar();
}
while(c != EOF && isdigit(c)){
a = (a << ) + (a << ) + (c ^ '');
c = getchar();
}
return f ? -a : a;
} const int MOD = , MAXN = ;
long long dp[MAXN + ][MAXN + ] , f[MAXN + ][MAXN + ] , g[MAXN + ][MAXN + ] , num[][MAXN + ] , jc[MAXN + ] , ny[MAXN + ] , N , M , K , ans; bool cmp(int a , int b){
return a > b;
} inline int poww(long long a , int b){
int times = ;
while(b){
if(b & )
times = times * a % MOD;
a = a * a % MOD;
b >>= ;
}
return times;
} signed main(){
#ifndef ONLINE_JUDGE
freopen("2538.in" , "r" , stdin);
//freopen("2538.out" , "w" , stdout);
#endif
jc[] = ;
for(long long i = ; i <= MAXN ; ++i)
jc[i] = jc[i - ] * i % MOD;
ny[MAXN] = poww(jc[MAXN] , MOD - );
for(long long i = MAXN - ; i >= ; --i)
ny[i] = ny[i + ] * (i + ) % MOD;
for(int i = ; i <= MAXN ; ++i)
dp[][i] = ;
for(int i = ; i <= MAXN ; ++i)
for(int j = ; j <= MAXN ; ++j)
dp[i][j] = (dp[i - ][j - ] + dp[i][j - ]) % MOD;
for(int i = ; i <= MAXN ; ++i)
f[][i] = ; for(int T = read() ; T ; --T){
N = read();
M = read();
K = read();
for(int i = ; i <= N ; ++i)
num[][i] = read();
sort(num[] + , num[] + N + , cmp);
for(int i = ; i <= N ; ++i)
num[][i] = read();
sort(num[] + , num[] + N + , cmp);
ans = ; for(int i = ; i <= N ; ++i)
for(int j = ; j <= N ; ++j){
f[i][j] = (1ll * f[i - ][j - ] * num[][j] + f[i][j - ]) % MOD;
g[i][j] = (g[i - ][j - ] + 1ll * (dp[i][j] - dp[i][j - ] + MOD) * num[][j] + g[i][j - ]) % MOD;
} for(int i = ; i < K ; ++i){
int sum1 = f[i][N] , sum2 = ;
for(int j = K - i ; N - j >= M - K ; ++j)
sum2 = (sum2 + 1ll * (g[K - i][j] - g[K - i][j - ] + MOD) * jc[N - j] % MOD * ny[M - K] % MOD * ny[N - j - (M - K)]) % MOD;
ans = (ans + 1ll * sum1 * sum2) % MOD;
} for(int i = K ; i < M ; ++i){
int sum1 = , sum2 = ;
for(int j = K - ; N - j >= i - (K - ) ; ++j)
sum1 = (sum1 + 1ll * (f[K - ][j] - f[K - ][j - ] + MOD) * jc[N - j] % MOD * ny[i - (K - )] % MOD * ny[N - j - (i - (K - ))]) % MOD;
for(int j = ; N - j >= M - i - ; ++j)
sum2 = (sum2 + 1ll * (g[][j] - g[][j - ] + MOD) * jc[N - j] % MOD * ny[M - i - ] % MOD * ny[N - j - (M - i - )]) % MOD;
ans = (ans + 1ll * sum1 * sum2) % MOD;
}
cout << ans << endl;
}
return ;
}
LOJ2538 PKUWC2018 Slay the Spire DP的更多相关文章
- [LOJ2538][PKUWC2018]Slay the Spire:DP
分析 学会新姿势!我们可以通过调整DP顺序来体现选取物品的优先顺序! 显然选取强化牌的最优策略是倍数从高到低,能选就选,最多选\(k-1\)张,选取攻击牌的最优策略是伤害从高到低,尽量少选,但最少选\ ...
- BZOJ.5467.[PKUWC2018]Slay the Spire(DP)
LOJ BZOJ 洛谷 哪张能力牌能乘攻击啊,太nb了叭 显然如果有能力牌,那么应该选最大的尽可能的打出\(k-1\)张. 然后下面说的期望都是乘总方案数后的,即所有情况的和.然后\(w_i\)统一用 ...
- [LOJ2538] [PKUWC2018] Slay the Spire
题目链接 LOJ:https://loj.ac/problem/2538 Solution 计数好题. 首先可以发现这题和期望没关系. 其次对于手上的一套牌,设我们有\(a\)张强化牌,那么: 如果\ ...
- 洛谷 P5299 - [PKUWC2018]Slay the Spire(组合数学+dp)
题面传送门 hot tea 啊--这种风格及难度的题放在省选 D2T1 左右还是挺喜闻乐见的罢 首先考虑对于固定的 \(m\) 张牌怎样求出最优的打牌策略,假设我们抽到了 \(p\) 张强化牌,攻击力 ...
- 【loj2538】 【PKUWC 2018】Slay the Spire dp
我们不难发现,假设抽了x张攻击牌,y张强化牌,那么肯定是打出尽可能多张的强化牌后,再开始出攻击牌(当然最少要一张攻击牌) 我们设G(i,j)表示:所有(抽到的攻击牌牌数为i,打出的攻击牌牌数为j)的方 ...
- 题解-PKUWC2018 Slay the Spire
Problem loj2538 Solution 在考场上当然要学会写暴力,考虑如果手上已经有了\(a\)张攻击牌和\(b\)张强化牌: 首先强化牌会在攻击牌之前用(废话),其次要将两种牌分别从大往小 ...
- [PKUWC2018] Slay the spire
Description 现在有 \(n\) 张强化牌和 \(n\) 张攻击牌: 攻击牌:打出后对对方造成等于牌上的数字的伤害. 强化牌:打出后,假设该强化牌上的数字为 \(x\),则其他剩下的攻击牌的 ...
- 【洛谷5299】[PKUWC2018] Slay the Spire(组合数学)
点此看题面 大致题意: 有\(n\)张强化牌\(a_i\)和\(n\)张攻击牌\(b_i\),每张牌有一个权值(强化牌的权值大于\(1\)),每张强化牌能使所有攻击牌的权值乘上这张强化牌的权值,每张攻 ...
- LOJ #2538. 「PKUWC 2018」Slay the Spire (期望dp)
Update on 1.5 学了 zhou888 的写法,真是又短又快. 并且空间是 \(O(n)\) 的,速度十分优秀. 题意 LOJ #2538. 「PKUWC 2018」Slay the Spi ...
随机推荐
- python之初识函数
函数: 函数是对功能或动作的封装. 函数的语法和定义: def 函数名(): 函数体 调用函数: 函数名() 函数返回值: return : 返回 def yue(): print("拿出手 ...
- 为什么radio没有出现单选效果?
原因是radio一定要设置相同的name,如下: <input type="radio" name="yunsuan" checked="che ...
- 解决如下问题:You are using pip version 8.1.1, however version 18.0 is available. You should consider upgrading via the 'pip install --upgrade pip' command.
问题描述: 今天想学习一下TUM数据集RGBD-Benchmark工具的使用,利用python进行相关操作时,缺少一个第三方模块,于是打算用pip进行安装,便出现如下图所示的问题. 解决办法: 执行如 ...
- 安装Django(1)
安装Django 注意:因为这是web项目将来要部署在Linux上,所以使用centos/ubuntu:因为Python3是将来的趋势,所以使用Python3做为开发语言.本人使用的开发模式操作系统: ...
- Expo大作战(三十八)--expo sdk api之 FileSystem(文件操作系统)
简要:本系列文章讲会对expo进行全面的介绍,本人从2017年6月份接触expo以来,对expo的研究断断续续,一路走来将近10个月,废话不多说,接下来你看到内容,讲全部来与官网 我猜去全部机翻+个人 ...
- MVP架构分析与搭建
一个项目的核心就是架构 1.什么是MVP:MVP是一种项目架构设计模式. 其实MVP的本质就是将view和model完全隔离出来,通过Presenter (主持人) 统一调度管理.
- 出现error: stray ‘\357’ in program的根源
分类: 编程语言/ C#/ 文章 这次又遇到这个这种问题,想找到它的根源.找到一个表格: The characters at a glance Here are all the printable c ...
- oracle FLASHBACK TABLE
闪回表 -- 开启行迁移 ALTER TABLE employees_test ENABLE ROW MOVEMENT; UPDATE employees_test SET salary = sala ...
- 【第一章】zabbix3.4监控WindowsCPU使用率磁盘IO磁盘事件日志监控阈值邮件报警详细配置
Windows安装zabbix-agent 监控Windows-CPU使用率 监控Windows-磁盘IO性能监控 监控Windows/Linux-磁盘触发器阈值更改 监控Windows-网卡自动发现 ...
- windwos安装RabbitMQ
目录 windows 安装RabbitMQ 安装erlang 安装rabbitmq 添加windows环境变量 检测rabbitmq状态 启动web管理插件 rabbitmq服务 windows 安装 ...