题目链接

LOJ:https://loj.ac/problem/2538

Solution

计数好题。

首先可以发现这题和期望没关系。

其次对于手上的一套牌,设我们有\(a\)张强化牌,那么:

  • 如果\(a\geqslant k-1\),那么我们显然是从大到小打出\(k-1\)张强化牌,最后打出一张最大的攻击牌。
  • \(\rm otherwise\),我们打出所有的强化牌,再从大到小打出攻击牌。

那么就可以\(dp\)了。

对于强化牌,我们从大到小排序,设\(f[i][j]\)表示当前考虑了前\(i\)种牌,打出了\(j\)种,所有方案的倍率之和。

那么可以得到转移:

  • \(j\leqslant k-1\),我们显然打出这张牌是最优的,\(f[i][j]=f[i-1][j]+f[i-1][j-1]\cdot w[i]\)。
  • \(\rm otherwise\),选或不选这张牌我们都不打出,\(f[i][j]=f[i-1][j]+f[i][j]\)。

对于攻击牌,我们从小到大排序,设\(g[i][j]\)表示当前考虑了前\(i\)种牌,打出了\(j\)种,所有方案的伤害之和。

  • \(j\leqslant m-(k-1)\),此时我们只能打出一张牌,\(g[i][j]=g[i-1][j]+\binom{i-1}{j-1}\cdot w[i]\)。
  • \(\rm otherwise\),我们可以打出多张牌,且应该尽量打后面的牌,\(g[i][j]=g[i-1][j-1]+g[i-1][j]+\binom{i-1}{j-1}\cdot w[i]\)。

第一位可以逆循环然后去掉。

最后答案就是\(ans=\sum_{i=0}^m f[i]g[m-i]\)。

#include<bits/stdc++.h>
using namespace std; void read(int &x) {
x=0;int f=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
} void print(int x) {
if(x<0) putchar('-'),x=-x;
if(!x) return ;print(x/10),putchar(x%10+48);
}
void write(int x) {if(!x) putchar('0');else print(x);putchar('\n');} #define lf double
#define ll long long const int maxn = 2e5+10;
const int inf = 1e9;
const lf eps = 1e-8;
const int mod = 998244353; int add(int x,int y) {return x+y>mod?x+y-mod:x+y;}
int del(int x,int y) {return x-y<0?x-y+mod:x-y;}
int mul(int x,int y) {return 1ll*x*y-1ll*x*y/mod*mod;} int n,m,k,a[maxn],b[maxn],f[maxn],g[maxn],fac[maxn],ifac[maxn],inv[maxn]; void prepare() {
inv[0]=inv[1]=fac[0]=ifac[0]=1;
for(int i=2;i<=3000;i++) inv[i]=mul(mod-mod/i,inv[mod%i]);
for(int i=1;i<=3000;i++) fac[i]=mul(fac[i-1],i);
for(int i=1;i<=3000;i++) ifac[i]=mul(ifac[i-1],inv[i]);
} int c(int x,int y) {return x>=y?mul(fac[x],mul(ifac[y],ifac[x-y])):0;} void solve() {
memset(f,0,sizeof f);
memset(g,0,sizeof g);
read(n),read(m),read(k);
for(int i=1;i<=n;i++) read(a[i]);
for(int i=1;i<=n;i++) read(b[i]);
sort(a+1,a+n+1,greater<int> ());
f[0]=1;
for(int i=1;i<=n;i++)
for(int j=n;j;j--)
if(j<=k-1) f[j]=add(f[j],mul(f[j-1],a[i]));
else f[j]=add(f[j],f[j-1]);
sort(b+1,b+n+1);
for(int i=1;i<=n;i++)
for(int j=n;j;j--)
if(j<=m-k+1) g[j]=add(g[j],mul(c(i-1,j-1),b[i]));
else g[j]=add(g[j],add(g[j-1],mul(c(i-1,j-1),b[i])));
int ans=0;
for(int i=0;i<=m;i++) ans=add(ans,mul(f[i],g[m-i]));
write(ans);
} int main() {
prepare();
int t;read(t);while(t--) solve();
return 0;
}

[LOJ2538] [PKUWC2018] Slay the Spire的更多相关文章

  1. LOJ2538 PKUWC2018 Slay the Spire DP

    传送门 不想放题面了,咕咕咕咕咕 这个期望明明是用来吓人的,其实要算的就是所有方案的最多伤害的和. 首先可以知道的是,能出强化牌就出强化牌(当然最后要留一张攻击牌出出去),且数字尽量大 所以说在强化牌 ...

  2. [LOJ2538][PKUWC2018]Slay the Spire:DP

    分析 学会新姿势!我们可以通过调整DP顺序来体现选取物品的优先顺序! 显然选取强化牌的最优策略是倍数从高到低,能选就选,最多选\(k-1\)张,选取攻击牌的最优策略是伤害从高到低,尽量少选,但最少选\ ...

  3. 题解-PKUWC2018 Slay the Spire

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

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

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

  5. [PKUWC2018] Slay the spire

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

  6. 【洛谷5299】[PKUWC2018] Slay the Spire(组合数学)

    点此看题面 大致题意: 有\(n\)张强化牌\(a_i\)和\(n\)张攻击牌\(b_i\),每张牌有一个权值(强化牌的权值大于\(1\)),每张强化牌能使所有攻击牌的权值乘上这张强化牌的权值,每张攻 ...

  7. 洛谷 P5299 - [PKUWC2018]Slay the Spire(组合数学+dp)

    题面传送门 hot tea 啊--这种风格及难度的题放在省选 D2T1 左右还是挺喜闻乐见的罢 首先考虑对于固定的 \(m\) 张牌怎样求出最优的打牌策略,假设我们抽到了 \(p\) 张强化牌,攻击力 ...

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

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

  9. BZOJ 5467 Slay the Spire

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

随机推荐

  1. 使用element-ui 的table 渲染数据遇到的问题

    通常我们使用一个table 来渲染服务的返回来的数据时,数据结构一般都是按row 来返回的,并且表头也是固定的 但是如果接口返回的数据结构不是我们想要的,表头也不确定时,我们该如何解析数据,将数据进行 ...

  2. crontab执行PHP

    在stackoverflow上看到一个问题:http://stackoverflow.com/questions/14015543/crontab-php-wget-or-curl 有三种通过cron ...

  3. 数据库c3p0配置文件

    <?xml version="1.0" encoding="UTF-8"?> <c3p0-config> <default-con ...

  4. 引领技术变革,腾讯云、腾讯WeTest和英特尔,合作布局云游戏

    WeTest 导读 ChinaJoy作为中国泛娱乐产业年度风向标,受到全球业界的高度关注.在本届ChinaJoy上,腾讯云.腾讯WeTest和英特尔,合作为游戏玩家.游戏开发者等业界人士联合展出了云游 ...

  5. 第二篇 CSS快速入门

    学CSS 和 JS的路线: 1. 首先,学会怎么找到标签.只有找到标签,才能操作标签——CSS通过选择器去找标签 2. 其次,学会怎么操作标签对象. CSS概述 CSS是Cascading Style ...

  6. Linux命令应用大词典-第18章 磁盘分区

    18.1 fdisk:分区表管理 18.2 parted:分区维护程序 18.3 cfdisk:基于磁盘进行分区操作 18.4 partx:告诉内核关于磁盘上分区的号码 18.5 sfdisk:用于L ...

  7. Python函数变量和返回值

    Python函数的全局变量和局部变量 1.不同的编程语言,程序可以分为函数和过程两大类,函数具有具体返回值,而过程则不具有具体的返回值,python只具有函数,因为对于它的一般函数,其返回值为所具体返 ...

  8. Ubuntu14.04 panic --not syncing: Attempt to kill init 解决方法

    Ubuntu14.04 panic --not syncing: Attempt to kill init 解决方法 工作电脑装了一个虚拟机玩玩,胡乱下载了一些软件,apt-get了不少操作,后来重启 ...

  9. git revert 与 git reset

    Git版本回滚之 git revert 与 git reset 在使用 git 的时候,如果错误push之后,经常会回滚版本. git的回滚有两种方式: revert命令:这种方式,是用一种反向的 p ...

  10. LeetCode 445——两数相加 II

    1. 题目 2. 解答 2.1 方法一 在 LeetCode 206--反转链表 和 LeetCode 2--两数相加 的基础上,先对两个链表进行反转,然后求出和后再进行反转即可. /** * Def ...