题目链接

题意分析

这个题其实不是期望

就是一共有\(C_{2n}^m\)种情况 每一种情况选择\(k\)张牌 然后求最大攻击值的总和

我们考虑

当前抽出了选出了\(i\)张强化牌 \(m-i\)张攻击牌

首先 可以肯定的是 能出强化牌就尽量出强化牌

我们去枚举\(i\)

如果\(i<k\) 那么就出\(i\)张强化牌 \(m-i\)张攻击牌

如果\(i≥k\) 那么就出\(k-1\)张强化牌 \(1\)张攻击牌

\(CDY(i,j)\)表示i张强化牌出\(j\)张 所有方案强化的倍率之和

\(WZY(i,j)\)表示i张攻击牌出\(j\)张 所有方案强化的攻击力之和

二者分别对应\(CDY(i,i)* WZY(m-i,k-i)\)以及\(CDY(i,k-1)* WZY(m-i,1)\)

根据乘法分配律

现在考虑如何计算 \(CDY\)以及\(WZY\)

首先 对于相同数量的牌 由于跟顺序没有关系 所以我们\(sort\)之后贪心选择最大即可

\(f(i,j)\)表示选了\(i\)张强化牌并且最靠前的是第\(j\)张牌

同理 \(g(i,j)\)同理

详细见代码

CODE:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<string>
#include<queue>
#include<map>
#include<stack>
#include<list>
#include<set>
#include<deque>
#include<vector>
#include<ctime>
#define ll long long
#define inf 0x7fffffff
#define N 3010
#define IL inline
#define M 1510
#define D double
#define mod 998244353
#define R register
using namespace std;
template<typename T>IL void read(T &_)
{
T __=0,___=1;char ____=getchar();
while(!isdigit(____)) {if(____=='-') ___=0;____=getchar();}
while(isdigit(____)) {__=(__<<1)+(__<<3)+____-'0';____=getchar();}
_=___ ? __:-__;
}
/*-------------OI使我快乐-------------*/
int T,n,m,k,ans;
int cdy[M],wzy[M];
int C[N][N];
int dp[M][M][2],sum[M];
IL int CDY(int x,int y)
{
if(x<y) return 0;
if(!y) return C[n][x];
int res=0;
for(R int j=x-y+1;j<=n-y+1;++j)
res=(res+1ll*dp[y][j][0]*C[j-1][x-y]%mod)%mod;
return res;
}
IL int WZY(int x,int y)
{
if(x<y) return 0;
int res=0;
for(R int j=x-y+1;j<=n-y+1;++j)
res=(res+1ll*dp[y][j][1]*C[j-1][x-y]%mod)%mod;
return res;
}
int main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
read(T);
for(R int i=0;i<=3000;++i) C[i][0]=1;
for(R int i=1;i<=3000;++i)
for(R int j=1;j<=i;++j)
C[i][j]=(1ll*C[i-1][j-1]+1ll*C[i-1][j])%mod;
// for(R int i=1;i<=10;++i)
// for(R int j=1;j<=i;++j)
// printf("%d%c",C[i][j],(j==i ? '\n':' '));
while(T--)
{
read(n);read(m);read(k);ans=0;
memset(dp,0,sizeof dp);
for(R int i=1;i<=n;++i) read(cdy[i]);
for(R int i=1;i<=n;++i) read(wzy[i]);
sort(cdy+1,cdy+n+1);
sort(wzy+1,wzy+n+1);
for(R int i=1;i<=n;++i)
{
dp[1][i][0]=cdy[i];
sum[i]=(sum[i-1]+cdy[i])%mod;
}
for(R int i=2;i<=n;++i)
{
for(R int j=1;j<=n-i+1;++j)
dp[i][j][0]=1ll*cdy[j]*(sum[n]-sum[j]+mod)%mod;
for(R int j=1;j<=n;++j)
sum[j]=(sum[j-1]+dp[i][j][0])%mod;
}
for(R int i=1;i<=n;++i)
{
dp[1][i][1]=wzy[i];
sum[i]=(sum[i-1]+wzy[i])%mod;
}
for(R int i=2;i<=n;++i)
{
for(R int j=1;j<=n-i+1;++j)
dp[i][j][1]=(1ll*wzy[j]*C[n-j][i-1]%mod+(sum[n]-sum[j]+mod)%mod)%mod;
for(R int j=1;j<=n;++j)
sum[j]=(sum[j-1]+dp[i][j][1])%mod;
}
for(R int i=0;i<m;++i)
{
if(i<k) ans=(ans+1ll*CDY(i,i)*WZY(m-i,k-i)%mod)%mod;
else ans=(ans+1ll*CDY(i,k-1)*WZY(m-i,1)%mod)%mod;
}
printf("%d\n",ans);
}
// fclose(stdin);
// fclose(stdout);
return 0;
}

HEOI 2019 RP++

「PKUWC2018」Slay the Spire的更多相关文章

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

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

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

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

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

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

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

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

    string detailURL = "https://www.xxx.xxx."; using (var w = new WWW(detailURL)) { yield retu ...

  2. md5,原理待续

    以前项目中copy出来的 import java.security.MessageDigest; public class MD5Util { /** * @todo MD5加码 生成32位md5码 ...

  3. Windows10远程桌面连接配置

    被控电脑在TP-Link路由器 1.基本设置 被控端电脑设置:1)被控端的电脑系统需要是Windows专业版或者企业版,家庭中文版的系统是不支持远程访问功能的: 2)被控端打开远程桌面功能,在系统的设 ...

  4. Ckeditor 中粘贴图片

    我们在ckeditor 中有上传图片,但是实际使用中这种手动上传图片方式并不是很方便,而是复制或者截图粘贴图片. 这里我们实现主要是获取对应的粘贴事件. CKEDITOR.instances[&quo ...

  5. [Selenium] 怎样判断是否适合自动化测试

    实施自动化测试前需要对软件开发过程进行分析,以观察其是否适合使用自动化测试.通常需要满足以下条件: 1)需求变动不频繁 2)项目周期足够长 3)自动化测试脚本可重复使用 4)手工测试无法完成或者需要大 ...

  6. ScrollView嵌套ListView只显示一行之计算的高度不正确的解决办法(转)

    ScrollView嵌套ListView只显示一行之计算的高度不正确的解决办法 分类: android应用开发2013-12-19 09:40 1045人阅读 评论(3) 收藏 举报 AndroidS ...

  7. docker 构建 spring boot项目

    在docker 开始部署springBoot项目 1.在centos7 ~ 创建一个文件夹docker 里面放置 上面的Dockerfile 和 springBoot 打包的项目docker_spri ...

  8. HTML5 桌面消息提醒

    Notification HTML5新属性,复制代码创建HTML文件,浏览器查看效果 <!DOCTYPE html> <html lang="en"> &l ...

  9. 数据结构(c语言版)文摘

    第一章  绪论 数据结构:是一门研究非数值计算的程序设计问题中计算机的操作对象以及它们之间的关系和操作等的学科. 数据:是对客观事物的符号表示,在计算机科学中是指所有能输入到计算机中并被计算机程序处理 ...

  10. B-spline Curves 学习之B样条曲线性质(5)

    B-spline Curves: Important Properties 本博客转自前人的博客的翻译版本,前几章节是原来博主的翻译内容,但是后续章节博主不在提供翻译,后续章节我在完成相关的翻译学习. ...