「PKUWC2018」Slay the Spire
题目链接
题意分析
这个题其实不是期望
就是一共有\(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的更多相关文章
- loj #2538. 「PKUWC2018」Slay the Spire
$ \color{#0066ff}{ 题目描述 }$ 九条可怜在玩一个很好玩的策略游戏:Slay the Spire,一开始九条可怜的卡组里有 \(2n\) 张牌,每张牌上都写着一个数字\(w_i\) ...
- LOJ2538. 「PKUWC2018」Slay the Spire【组合数学】
LINK 思路 首先因为式子后面把方案数乘上了 所以其实只用输出所有方案的攻击力总和 然后很显然可以用强化牌就尽量用 因为每次强化至少把下面的牌翻一倍,肯定是更优的 然后就只有两种情况 强化牌数量少于 ...
- loj2538 「PKUWC2018」Slay the Spire 【dp】
题目链接 loj2538 题解 比较明显的是,由于强化牌倍数大于\(1\),肯定是能用强化牌尽量用强化牌 如果强化牌大于等于\(k\),就留一个位给攻击牌 所以我们将两种牌分别排序,企图计算\(F(i ...
- 【LOJ】#2538. 「PKUWC2018」Slay the Spire
题解 由于强化卡都是大于1的,我们分析一下就会发现,尽可能多的用强化卡,至少用一张攻击卡,一定是每组卡牌的最优选择 所以我们把攻击卡和强化卡从大到小排序 我们设\(g[i][j]\)表示前i张卡牌里选 ...
- LOJ #2538. 「PKUWC 2018」Slay the Spire (期望dp)
Update on 1.5 学了 zhou888 的写法,真是又短又快. 并且空间是 \(O(n)\) 的,速度十分优秀. 题意 LOJ #2538. 「PKUWC 2018」Slay the Spi ...
- Loj #2542. 「PKUWC2018」随机游走
Loj #2542. 「PKUWC2018」随机游走 题目描述 给定一棵 \(n\) 个结点的树,你从点 \(x\) 出发,每次等概率随机选择一条与所在点相邻的边走过去. 有 \(Q\) 次询问,每次 ...
- 「PKUWC2018」随机游走(min-max容斥+FWT)
「PKUWC2018」随机游走(min-max容斥+FWT) 以后题目都换成这种「」形式啦,我觉得好看. 做过重返现世的应该看到就想到 \(min-max\) 容斥了吧. 没错,我是先学扩展形式再学特 ...
- 「PKUWC2018」猎人杀
「PKUWC2018」猎人杀 解题思路 首先有一个很妙的结论是问题可以转化为已经死掉的猎人继续算在概率里面,每一轮一直开枪直到射死一个之前没死的猎人为止. 证明,设所有猎人的概率之和为 \(W\) , ...
- loj#2537. 「PKUWC2018」Minimax
题目链接 loj#2537. 「PKUWC2018」Minimax 题解 设\(f_{u,i}\)表示选取i的概率,l为u的左子节点,r为u的子节点 $f_{u,i} = f_{l,i}(p \sum ...
随机推荐
- 用 AutoHotKey 随时记录所想
别被标题咋呼了,其实很简单,按下快捷键自动打开指定文本文档,自动加上当前时间日期,适合像我这种无聊的人记录生活. ;Alt+X 调出 !X:: ;获取当前日期时间并保存到剪贴板 d = @rhinoc ...
- 和大于S的最小子数组 · Minimum Size Subarray Sum
[抄题]: 给定一个由 n 个正整数组成的数组和一个正整数 s ,请找出该数组中满足其和 ≥ s 的最小长度子数组.如果无解,则返回 -1. 给定数组 [2,3,1,2,4,3] 和 s = 7, 子 ...
- JavaScript RegExp.exec() 方法
定义和用法: exec() 方法用于检索字符串中的正则表达式的匹配. 语法: RegExpObject.exec(string); RegExpObject:必须参数,正则表达式: string:必须 ...
- Android内核的编译与测试
1.下载Android内核 source.android.com/source->Downloading and Building Building Kernels 大概要花2个小时,其源码在培 ...
- IntelliJ IDEA 2017版 SpringBoot徒手书写HelloWorld
1.打开编译器,选择File---->New---->Project 2.弹出设置界面,选择如图样式的1.2.3 3.设置包名称 4.继续next 5.finish完成即可 6.自动生成目 ...
- 加载 bean*.xml
入口 ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:bean*.xml"); /** ...
- [PHP]socket的连接超时 与 读取/写入超时
socket处理时有两种超时 , 分为连接超时 和 读取/写入数据超时 1. stream_socket_client 函数中的超时时间是连接超时 , 默认是php.ini中的default_sock ...
- EJB学习手记
周末两天,看了两天的ejb知识.公司有个转发消息的程序,里面是根据ejb/jms+cdi/event做的,这些之前没接触过. 总而言之,从中学到了很多东西,从ejb到webservice. jboss ...
- asp.net 使用Oracle数据库
asp.net下使用oracle会发生“未能加载文件或程序集‘Oracle.DataAccess’或它的某一个依赖项”的错误.这说明Oracle的驱动没有安装好,或者版本不对的错误. 1.检查Orac ...
- Solr查询query效果对比
q条件 默认分词(org.apache.solr.analysis.TokenizerChain) "parsedquery" IK分词(org.wltea.analyzer.lu ...