BZOJ 5467 Slay the Spire
BZOJ 5467 Slay the Spire
- 我的概率基础也太差了.jpg
大概就是这样,因为强化牌至少翻倍,所以打出的牌必定是全部的强化牌或者$k-1$个强化牌,然后剩余的机会打出最大的几个攻击牌。
我们对于强化牌和攻击牌分别做,并且显然,排序并不会影响答案。
$f[i][j]$表示前$i$张牌,取到$j$张,第$i$张必定取的最大强化值之积,$g[i][j]$表示前$i$张攻击牌,取到$j$张,第$i$张必定取的最大伤害和。(一般来说,应该先考虑第$i$张不必需取的最大值,但是由于那样设计状态并不能优化成$n^2$,所以只能选择第$i$张必须选的答案)
$f[i][j]=a_i\times \sum\limits_{k=j-1}^{i-1} f[k][j-1]$
$g[i][j]=C(i-1,j-1)\times b_i+\sum\limits_{k=j-1}^{i-1} g[k][j-1]$
然后剩下的就是如何计算答案了。
那么很显然,我们要求的是前$n$张排中,选择$j$个,第$n$个不必需选择的答案。
因此设$F(i,j)$表示摸到$i$张,选择$j$个的最大强化之积。那么很显然,$F(i,j)=\sum\limits_{k=i}^nf[k][j]\times C(n-k,i-j)$
同时设$G(i,j)$表示摸到$i$张,选择$j$个的最大伤害之和。那么很显然,$G(i,j)=\sum\limits_{k=i}^n g[k][j]\times C(n-k,i-j)$
同样,根据我们最初得到的结论,$ans=\sum\limits_{i=0}^{k-1}F(i,i)\times G(m-i,k-i)+\sum\limits_{i=k}^m F(i,k-1)\times G(m-i,1)$
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <queue>
#include <iostream>
#include <bitset>
using namespace std;
#define N 3005
#define ll long long
#define mod 998244353
int f[N][N],g[N][N],n,k,a[N],b[N],m,sum[N],C[N][N];
void init()
{
for(int i=0;i<=3000;i++)
{
C[i][0]=1;
for(int j=1;j<=i;j++)C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod;
}
}
int F(int x,int y)
{
if(x<y)return 0;if(!y)return C[n][x];int ret=0;
for(int i=x-y+1;i<=n-y+1;i++)ret=(ret+(ll)f[y][i]*C[i-1][x-y])%mod;
return ret;
}
int G(int x,int y)
{
if(x<y)return 0;int ret=0;
for(int i=x-y+1;i<=n-y+1;i++)ret=(ret+(ll)g[y][i]*C[i-1][x-y])%mod;
return ret;
}
void solve()
{
scanf("%d%d%d",&n,&m,&k);
// memset(f,0,sizeof(f));memset(g,0,sizeof(g));
for(int i=1;i<=n;i++)
for(int j=1;j<=n-i+1;j++)
f[i][j]=g[i][j]=0;
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
for(int i=1;i<=n;i++)scanf("%d",&b[i]);
sort(a+1,a+n+1);sort(b+1,b+n+1);
for(int i=1;i<=n;i++)f[1][i]=a[i],sum[i]=(sum[i-1]+a[i])%mod;
for(int i=2;i<=n;i++)
{
for(int j=1;j<=n-i+1;j++)f[i][j]=(ll)a[j]*(sum[n]-sum[j]+mod)%mod;
for(int j=1;j<=n-i+1;j++)sum[j]=(sum[j-1]+f[i][j])%mod;
for(int j=n-i+2;j<=n;j++)sum[j]=sum[j-1];
}
for(int i=1;i<=n;i++)g[1][i]=b[i],sum[i]=(sum[i-1]+b[i])%mod;
for(int i=2;i<=n;i++)
{
for(int j=1;j<=n-i+1;j++)g[i][j]=((ll)b[j]*C[n-j][i-1]+sum[n]-sum[j]+mod)%mod;
for(int j=1;j<=n-i+1;j++)sum[j]=(sum[j-1]+g[i][j])%mod;
for(int j=n-i+2;j<=n;j++)sum[j]=sum[j-1];
}
int ans=0;
for(int i=0;i<m;i++)
{
if(i<k)ans=(ans+(ll)F(i,i)*G(m-i,k-i))%mod;
else ans=(ans+(ll)F(i,k-1)*G(m-i,1))%mod;
}
printf("%d\n",ans);
}
int main(){init();int T;scanf("%d",&T);while(T--)solve();return 0;}
BZOJ 5467 Slay the Spire的更多相关文章
- LOJ #2538. 「PKUWC 2018」Slay the Spire (期望dp)
Update on 1.5 学了 zhou888 的写法,真是又短又快. 并且空间是 \(O(n)\) 的,速度十分优秀. 题意 LOJ #2538. 「PKUWC 2018」Slay the Spi ...
- loj #2538. 「PKUWC2018」Slay the Spire
$ \color{#0066ff}{ 题目描述 }$ 九条可怜在玩一个很好玩的策略游戏:Slay the Spire,一开始九条可怜的卡组里有 \(2n\) 张牌,每张牌上都写着一个数字\(w_i\) ...
- BZOJ.5467.[PKUWC2018]Slay the Spire(DP)
LOJ BZOJ 洛谷 哪张能力牌能乘攻击啊,太nb了叭 显然如果有能力牌,那么应该选最大的尽可能的打出\(k-1\)张. 然后下面说的期望都是乘总方案数后的,即所有情况的和.然后\(w_i\)统一用 ...
- [PKUWC2018] Slay the spire
Description 现在有 \(n\) 张强化牌和 \(n\) 张攻击牌: 攻击牌:打出后对对方造成等于牌上的数字的伤害. 强化牌:打出后,假设该强化牌上的数字为 \(x\),则其他剩下的攻击牌的 ...
- 题解-PKUWC2018 Slay the Spire
Problem loj2538 Solution 在考场上当然要学会写暴力,考虑如果手上已经有了\(a\)张攻击牌和\(b\)张强化牌: 首先强化牌会在攻击牌之前用(废话),其次要将两种牌分别从大往小 ...
- LOJ2538 PKUWC2018 Slay the Spire DP
传送门 不想放题面了,咕咕咕咕咕 这个期望明明是用来吓人的,其实要算的就是所有方案的最多伤害的和. 首先可以知道的是,能出强化牌就出强化牌(当然最后要留一张攻击牌出出去),且数字尽量大 所以说在强化牌 ...
- LOJ2538. 「PKUWC2018」Slay the Spire【组合数学】
LINK 思路 首先因为式子后面把方案数乘上了 所以其实只用输出所有方案的攻击力总和 然后很显然可以用强化牌就尽量用 因为每次强化至少把下面的牌翻一倍,肯定是更优的 然后就只有两种情况 强化牌数量少于 ...
- PKUWC Slay The Spire
题面链接 LOJ sol 好神啊.果然\(dp\)还是做少了,纪录一下现在的思维吧\(QAQ\). 我们首先可以发现期望是骗人的,要不然他乘的是什么xjb玩意. 其实就是要求所有方案的最优方案和. 因 ...
- loj2538 「PKUWC2018」Slay the Spire 【dp】
题目链接 loj2538 题解 比较明显的是,由于强化牌倍数大于\(1\),肯定是能用强化牌尽量用强化牌 如果强化牌大于等于\(k\),就留一个位给攻击牌 所以我们将两种牌分别排序,企图计算\(F(i ...
随机推荐
- UoW中修改VIM的配色方案
在WIN10中提供Bash on Ubuntu on Windows,即在win中提供一个Ubuntu子系统,可以使用bash.该系统中自带的VIM的配色方案colorscheme为默认的,不怎么好, ...
- Nginx 配置下载附件让浏览器提示用户是否保存
Nginx配置下载附件让浏览器提示用户是否保存 by:授客 QQ:1033553122 测试环境 nginx-1.10.0 问题描述: 前端页面,IE11浏览器下请求下载附件模板,针对xls ...
- Python __exit__,__enter__函数with语句的组合应用
__exit__,__enter__函数with语句的组合应用 by:授客 QQ:1033553122 简介 设计对象类时,我们可以为对象类新增两个方法,一个是__enter(self)__,一个 ...
- Android为TV端助力 比较完善json请求格式
public static String getHttpText(String url) { if (MyApplication.FOR_DEBUG) { Log.i(TAG, "[getH ...
- Javascript数组系列四之数组的转换与排序Sort方法
今天我们继续来介绍 Javascirpt 数组中的方法,也是数组系列的第四篇文章,因为数组的方法众多,每篇文章我们都对数组的每个方法都有比较细致的描述,只要你能够从中成长一点点,那我们的目的就达到了, ...
- Java中线程的同步问题
在生活中我们时常会遇到同步的问题,而且大多数的实际问题都是线程的同步问题 我这里以生活中的火车售票来进行举例: 假设现在我们总共有1000张票要进行出售,共有10个出售点,那么当售票到最后只有一张票时 ...
- Docker & pure-ftpd 快速加建 FTP 服务器
项目需要进行升级服务,现在需要基于centos 7使用docker来快速打架一个FTP环境来方便本地文件上传. 本次使用的是 pure-ftpd docker镜像,有关镜像使用的详细信息,本人是从 h ...
- Oracle解锁scott用户
解决: (1)conn sys/sys as sysdba;//以DBA的身份登录 (2)alter user scott account unlock;// 然后解锁 (3)conn scott/t ...
- [20181214]open file using O_DIRECT.txt
[20181214]open file using O_DIRECT.txt --//因为一个测试需要,需要写一个测试小例子,验证使用O_DIRECT打开文件每次都是从磁盘读取.--//没想到浪费1个 ...
- 区块链会与io域名有什么关系
为什么区块链会与io域名有这么大的联系? 近几年,区块链成为各国央行到国内外各大商业银行.联合国.国际货币基金组织到许多国家政府研究机构讨论的热点,"区块链+"应用创新正在成为引领 ...