[LOJ2538][PKUWC2018]Slay the Spire:DP
分析
学会新姿势!我们可以通过调整DP顺序来体现选取物品的优先顺序!
显然选取强化牌的最优策略是倍数从高到低,能选就选,最多选\(k-1\)张,选取攻击牌的最优策略是伤害从高到低,尽量少选,但最少选\(1\)张。
我们可以把强化牌从大到小排序,把攻击牌从小到大排序,令\(f[i][j]\)表示考虑了最大的\(i\)张强化牌,其中所有可选的强化牌有\(j\)张的情况的最优策略下的强化倍数和,\(g[i]\)表示考虑了最小的\(i\)张攻击牌,其中所有可选的攻击牌有\(j\)张的情况的最优策略下的伤害和。
状态转移方程如下:
\]
\]
\]
\]
代码
#include <bits/stdc++.h>
#define rin(i,a,b) for(int i=(a);i<=(b);++i)
#define irin(i,a,b) for(int i=(a);i>=(b);--i)
#define trav(i,a) for(int i=head[a];i;i=e[i].nxt)
#define Size(a) (int)a.size()
#define pb push_back
#define mkpr std::make_pair
#define fi first
#define se second
#define lowbit(a) ((a)&(-(a)))
typedef long long LL;
using std::cerr;
using std::endl;
inline int read(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
const int MAXN=3005;
const int MOD=998244353;
int n,m,k,a[MAXN],b[MAXN],f[MAXN],g[MAXN];
int fac[MAXN],invf[MAXN];
inline int qpow(int x,int y){
int ret=1,tt=x%MOD;
while(y){
if(y&1)ret=1ll*ret*tt%MOD;
tt=1ll*tt*tt%MOD;
y>>=1;
}
return ret;
}
inline int binom(int n,int m){
if(n<0||m<0||n<m)return 0;
return 1ll*fac[n]*invf[n-m]%MOD*invf[m]%MOD;
}
void init(){
fac[0]=1;rin(i,1,n)fac[i]=1ll*fac[i-1]*i%MOD;
invf[n]=qpow(fac[n],MOD-2);irin(i,n-1,0)invf[i]=1ll*invf[i+1]*(i+1)%MOD;
}
int main(){
n=3000;init();
int T=read();
while(T--){
n=read(),m=read(),k=read();
rin(i,1,n)a[i]=read();
rin(i,1,n)b[i]=read();
std::sort(a+1,a+n+1);
std::sort(b+1,b+n+1);
rin(i,0,m)f[i]=g[i]=0;
f[0]=1,g[0]=0;
irin(i,n,1)irin(j,std::min(n-i+1,m),1){
if(j<=k-1)f[j]=(f[j]+1ll*f[j-1]*a[i])%MOD;
else f[j]=(f[j]+f[j-1])%MOD;
}
rin(i,1,n)irin(j,std::min(i,m),1){
if(m-j<k-1)g[j]=(g[j]+1ll*binom(i-1,j-1)*b[i]+g[j-1])%MOD;
else g[j]=(g[j]+1ll*binom(i-1,j-1)*b[i])%MOD;
}
int ans=0;
rin(i,0,m)ans=(ans+1ll*f[i]*g[m-i])%MOD;
printf("%d\n",ans);
}
return 0;
}
[LOJ2538][PKUWC2018]Slay the Spire:DP的更多相关文章
- LOJ2538 PKUWC2018 Slay the Spire DP
传送门 不想放题面了,咕咕咕咕咕 这个期望明明是用来吓人的,其实要算的就是所有方案的最多伤害的和. 首先可以知道的是,能出强化牌就出强化牌(当然最后要留一张攻击牌出出去),且数字尽量大 所以说在强化牌 ...
- [LOJ2538] [PKUWC2018] Slay the Spire
题目链接 LOJ:https://loj.ac/problem/2538 Solution 计数好题. 首先可以发现这题和期望没关系. 其次对于手上的一套牌,设我们有\(a\)张强化牌,那么: 如果\ ...
- LOJ #2538. 「PKUWC 2018」Slay the Spire (期望dp)
Update on 1.5 学了 zhou888 的写法,真是又短又快. 并且空间是 \(O(n)\) 的,速度十分优秀. 题意 LOJ #2538. 「PKUWC 2018」Slay the Spi ...
- loj2538 「PKUWC2018」Slay the Spire 【dp】
题目链接 loj2538 题解 比较明显的是,由于强化牌倍数大于\(1\),肯定是能用强化牌尽量用强化牌 如果强化牌大于等于\(k\),就留一个位给攻击牌 所以我们将两种牌分别排序,企图计算\(F(i ...
- BZOJ.5467.[PKUWC2018]Slay the Spire(DP)
LOJ BZOJ 洛谷 哪张能力牌能乘攻击啊,太nb了叭 显然如果有能力牌,那么应该选最大的尽可能的打出\(k-1\)张. 然后下面说的期望都是乘总方案数后的,即所有情况的和.然后\(w_i\)统一用 ...
- 洛谷 P5299 - [PKUWC2018]Slay the Spire(组合数学+dp)
题面传送门 hot tea 啊--这种风格及难度的题放在省选 D2T1 左右还是挺喜闻乐见的罢 首先考虑对于固定的 \(m\) 张牌怎样求出最优的打牌策略,假设我们抽到了 \(p\) 张强化牌,攻击力 ...
- 题解-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\)),每张强化牌能使所有攻击牌的权值乘上这张强化牌的权值,每张攻 ...
随机推荐
- Go语言中的切片(十)
go中数组的长度是固定的,且不同长度的数组是不同类型,这样的限制带来不少局限性.于是切片就来了,切片(Slice)是一个拥有相同类型元素的可变长度的序列.它是基于数组类型做的一层封装.它非常灵活,支持 ...
- C++学习 之 类的继承中的虚函数(笔记)
1.多态行为 多态是面向对象语言的一种特征,让我们能够以类似的方式处理不同类型的对象.在C++中我们可以通过继承层次结构实现子类型多态. 我们可以通过下面的代码进一步了解多态: #include< ...
- 导出excel模版
方法一: public void ToExcel(){ //第一步:获取模版物理路径 string file_1 = Server.MapPath("/Content/Excel/downE ...
- 图片哈希概论及python中如何实现对比两张相似的图片
Google 以图搜图的原理,其中的获取图片 hash 值的方法就是 AHash. 每张图片都可以通过某种算法得到一个 hash 值,称为图片指纹,两张指纹相近的图片可以认为是相似图片. 以图搜图的原 ...
- NLP 基于kashgari和BERT实现中文命名实体识别(NER)
准备工作,先准备 python 环境,下载 BERT 语言模型 Python 3.6 环境 需要安装kashgari Backend pypi version desc TensorFlow 2.x ...
- java笔记web
1,spring请求同,返回同一个界面 Dubbo消费者无法连接到生产者提供的服务?内网IP? https://blog.csdn.net/xlgen157387/article/details/52 ...
- appium 自动化测试环境搭建
最近再学习appium,把学习的过程记录下来,以防止到时候 换个电脑就不知道这么安装搭建appium环境了. 环境搭建: 0.JDK环境是必备的,这里大家自行百度, 1.安装 node 环境,前辈 ...
- Session的生命周期和工作原理
一.什么是Session,如何使用?Session是用于存放用户与web服务器之间的会话,即服务器为客户端开辟的存储空间. 由于客户端与服务器之间的会话是无状态的机制,Session则可用于关联访问, ...
- Delphi ComboBox组件
- 16、Nginx Rewrite重写
1.Rewrite基本概述 1.1.什么是rewrite Rewrite主要实现url地址重写, 以及地址重定向,就是将用户请求web服务器的地址重新定向到其他URL的过程. 1.2.Rewrite使 ...