题面链接

LOJ

sol

好神啊。果然\(dp\)还是做少了,纪录一下现在的思维吧\(QAQ\)。

我们首先可以发现期望是骗人的,要不然他乘的是什么xjb玩意。

其实就是要求所有方案的最优方案和。

因为\(w_i\)是大于1的,所以能强化先强化,再从大往小打攻击牌。

那么我们枚举用了\(a\)张强化,\(b\)张攻击。

若\(a<k\),显然强化牌选完,攻击牌从大到小。

否则,选前\(k-1\)大的强化牌,再选最大的攻击牌。

我们如何做到最优呢,这里有一个套路,先排序,这样可以保证每一种方案这一定是最优的。

设\(f[i][j]\)表示用了\(i\)张强化牌最后一张是第\(j\)张的所有的方案的乘积。

设\(g[i][j]\)表示用了\(i\)张攻击牌最后一张是第\(j\)张的所有的方案的和。

注意我们是求所有的方案。

设\(F[i][j]\)表示取了\(i\)张强化牌,用了\(j\)张的方案的乘积。

设\(G[i][j]\)表示取了\(i\)张攻击牌,用了\(j\)张的方案的和。

那么有

\[F[x][y]=\sum_{i=1}^nf[y][i]*\binom{n-i}{x-y}
\]

\[G[x][y]=\sum_{i=1}^ng[y][i]*\binom{n-i}{x-y}
\]

一张强化牌都不能要的时候。\(F[x][y]=\binom{n}{x}\)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define gt getchar()
#define ll long long
#define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
inline int in()
{
int k=0;char ch=gt;
while(ch<'-')ch=gt;
while(ch>'-')k=k*10+ch-'0',ch=gt;
return k;
}
const int N=3005,YL=998244353;
inline int MO(const int &a){return a>=YL?a-YL:a;}
inline int ksm(int a,int k){int r=1;while(k){if(k&1)r=1ll*r*a%YL;a=1ll*a*a%YL,k>>=1;}return r;}
int f[N][N],g[N][N],a[N],b[N],sum[N],fac[N],fnv[N],n,m,k;
inline int C(int x,int y){return y>x?0:1ll*fac[x]*fnv[y]%YL*fnv[x-y]%YL;}
inline int qh(int x,int y)
{
if(y>x)return 0;if(!y)return C(n,x);
int res=0;
for(int i=1;i<=n;++i)
res=MO(res+1ll*f[y][i]*C(n-i,x-y)%YL);
return res;
}
inline int gj(int x,int y)
{
if(y>x)return 0;if(!y)return 0;
int res=0;
for(int i=1;i<=n;++i)
res=MO(res+1ll*g[y][i]*C(n-i,x-y)%YL);
return res;
}
int main()
{
fac[0]=fnv[0]=1;
for(int i=1;i<=3000;++i)fac[i]=1ll*fac[i-1]*i%YL;fnv[3000]=ksm(fac[3000],YL-2);
for(int i=3000;i>=1;--i)fnv[i-1]=1ll*fnv[i]*i%YL;
int t=in();
while(t--)
{
n=in(),m=in(),k=in();
for(int i=1;i<=n;++i)a[i]=in();
for(int i=1;i<=n;++i)b[i]=in();
std::sort(a+1,a+n+1,std::greater<int>());
std::sort(b+1,b+n+1,std::greater<int>());
for(int i=1;i<=n;++i)f[1][i]=a[i],sum[i]=MO(sum[i-1]+a[i]);
for(int i=2;i<=n;++i)
{
for(int j=1;j<=n;++j)f[i][j]=1ll*a[j]*sum[j-1]%YL;
for(int j=1;j<=n;++j)sum[j] =MO(sum[j-1]+f[i][j]);
}
for(int i=1;i<=n;++i)g[1][i]=b[i],sum[i]=MO(sum[i-1]+b[i]);
for(int i=2;i<=n;++i)
{
for(int j=1;j<=n;++j)g[i][j]=MO(1ll*b[j]*C(j-1,i-1)%YL+sum[j-1]);
for(int j=1;j<=n;++j)sum[j] =MO(sum[j-1]+g[i][j]);
}
int ans=0;
for(int a=0,t=std::min(n,m);a<=t;++a)
{
int b=m-a;if(b>n||b<0)continue;
ans=MO(ans+(a<k?1ll*qh(a,a)*gj(b,k-a)%YL:1ll*qh(a,k-1)*gj(b,1)%YL));
}
printf("%d\n",ans);
}
return 0;
}

PKUWC Slay The Spire的更多相关文章

  1. LOJ #2538. 「PKUWC 2018」Slay the Spire (期望dp)

    Update on 1.5 学了 zhou888 的写法,真是又短又快. 并且空间是 \(O(n)\) 的,速度十分优秀. 题意 LOJ #2538. 「PKUWC 2018」Slay the Spi ...

  2. BZOJ 5467 Slay the Spire

    BZOJ 5467 Slay the Spire 我的概率基础也太差了.jpg 大概就是这样,因为强化牌至少翻倍,所以打出的牌必定是全部的强化牌或者$k-1$个强化牌,然后剩余的机会打出最大的几个攻击 ...

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

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

  4. loj2538 「PKUWC 2018」Slay the Spire

    pkusc 快到了--做点题涨涨 rp. ref我好菜啊QAQ. 可以发现期望只是一个幌子.我们的目的是:对于所有随机的选择方法(一共 \(\binom{2n}{m}\)种),这些选择方法都最优地打出 ...

  5. [LOJ #2538][PKUWC 2018]Slay the Spire

    题目大意:一开始有 $2n$ 张牌,每张牌上都写着一个数字 $w_i$,有两种的牌,每种类型各 $n$ 张: 1.攻击牌:打出后对对方造成牌上的数字的伤害. 2.强化牌:打出后,设数字为 $x$,则其 ...

  6. 【loj2538】 【PKUWC 2018】Slay the Spire dp

    我们不难发现,假设抽了x张攻击牌,y张强化牌,那么肯定是打出尽可能多张的强化牌后,再开始出攻击牌(当然最少要一张攻击牌) 我们设G(i,j)表示:所有(抽到的攻击牌牌数为i,打出的攻击牌牌数为j)的方 ...

  7. BZOJ.5467.[PKUWC2018]Slay the Spire(DP)

    LOJ BZOJ 洛谷 哪张能力牌能乘攻击啊,太nb了叭 显然如果有能力牌,那么应该选最大的尽可能的打出\(k-1\)张. 然后下面说的期望都是乘总方案数后的,即所有情况的和.然后\(w_i\)统一用 ...

  8. [PKUWC2018] Slay the spire

    Description 现在有 \(n\) 张强化牌和 \(n\) 张攻击牌: 攻击牌:打出后对对方造成等于牌上的数字的伤害. 强化牌:打出后,假设该强化牌上的数字为 \(x\),则其他剩下的攻击牌的 ...

  9. 题解-PKUWC2018 Slay the Spire

    Problem loj2538 Solution 在考场上当然要学会写暴力,考虑如果手上已经有了\(a\)张攻击牌和\(b\)张强化牌: 首先强化牌会在攻击牌之前用(废话),其次要将两种牌分别从大往小 ...

随机推荐

  1. Aria2 Linux 完整安装及使用教程

    Aria2 嘛,主要是用来离线下载,功能强大,支持 http/https 直链.ftp.电驴.磁力链接等等,且可以跨平台使用,配合网页端操作,简直是一代下载神器. 安装 Debian/Ubuntu: ...

  2. k8s踩坑记第1篇--rc无法创建

    六一快乐!!! 什么是k8s,我不想解释,百度资料有很多,本系列只踩坑,不科普. 问题描述: 做Hello World的例子,结果get pods一直显示没有资源? 应用配置代码: apiVersio ...

  3. GitHub笔记(二)——远程仓库的操作

    二 远程仓库 1 创建联系 第1步:创建SSH Key.在用户主目录下,看看有没有.ssh目录,如果有,再看看这个目录下有没有id_rsa和id_rsa.pub这两个文件,如果已经有了,可直接跳到下一 ...

  4. 机器学习基础 --- numpy的基本使用

    一.numpy的简介 numpy是Python的一种开源的数值计算扩展库.这种工具可用来存储和处理大型矩阵,比Python自身的嵌套列表(nested list structure)结构要高效的多(该 ...

  5. 笔试题——C++开发简单记录错误模块

    题目:链接:https://www.nowcoder.com/questionTerminal/67df1d7889cf4c529576383c2e647c48 来源:牛客网 解析及代码来源:http ...

  6. Array.Copy 数据是克隆吗?

    偶然看到 Array.Copy 方法的时候,想到,它是否是克隆,又是否是深克隆. 做了一个测试 public class abc { public string hello; } [TestMetho ...

  7. [cmake] Basic Tutorial

    Basic Project The most basic porject is an executable built from source code file. CMakeLists.txt cm ...

  8. TeamWork#3,Week5,Scrum Meeting 11.14

    根据最近项目出现的问题,我们明确了需要补充的工作,添加了几项任务. 成员 已完成 待完成 彭林江 由于网站信息更新,正在调整爬虫程序结构 更换爬虫结构 郝倩 由于网站信息更新,正在调整爬虫程序结构 更 ...

  9. Task 6.3 场景调研

    1.背景: (1)典型用户:信息1303班王银凤 (2)用户的需求/迫切需要解决的问题:她们宿舍上网一直使用的是外网,一年400的一种“套餐”.这种是按小时计算的,在校的时间平均下来一天可以用7 . ...

  10. visualStudo编译c程序, 提示函数unSafe问题

    问题描述: 在利用visualStudo进行C语言编程时,若C语言源程序中有print,freopen等函数时,IDE软件总是unSafe,而且无法通过编译. 解决方案: 在<视图>中找到 ...