「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 ...
随机推荐
- mybatis使用foreach进行批量插入和删除操作
一.批量插入 1.mapper层 int insertBatchRoleUser(@Param("lists") List<RoleUser> lists);//@Pa ...
- 综合:bool类型 命名空间 输入输出
----------siwuxie095 题目要求: 使用一个函数找出一个整型数组中的最大值或最小值 注意: 1.直接书写 cin cout endl, ...
- [leetcode]206. Reverse Linked List反转链表
Reverse a singly linked list. Input: 1->2->3->4->5->NULL Output: 5->4->3->2- ...
- Common issue on financial information exchange (FIX) Connectivity[z]
FIX Protocol Session Connectivity Hi guys, in this post I would like share my experience with financ ...
- 全球数据库-->基金/管理产品-->基金分析/新闻/报告
加拿大共同基金 澳大利亚投资信托 美国ETF 美国共同基金 英国投资信托基金 名称 分析师名称 分析日期 晨星分析师评级 晨星简报
- Nginx搭建后,图片存储在Tomcat上,前端无法回显图片问题
一.Nginx与Tomcat连接搭建的环境,Nginx设置了前端的访问路径为 (1)前端代码配置: root /usr/local/nginx/html; index index.html index ...
- ios9出现的问题
升级后需要注意两个地方 1 在build Settings 搜索bitcode 设置成no 2 在info.plist里添加以下属性 程序中报错: App Transport Security ...
- Android-工作总结-LX-2018-08-20-判断数据库表字段是否为空
问题的因素: 调试了一上午,我要判断数据库表的name字段是否为空,使用了TextUtils.isEmpty(nameStr):来判断name字段是否为空,明明数据库是没有值,却一直显示有值,然后还去 ...
- linux服务器下配置多tomcat
车辆交易用的系统模块,正在做.老板要看看,以便车城那边的人提出意见.于是在服务器上再次增加一个tomcat. 以前是配置过的,配置过程其实很简单,这次太大意了,找了半天问题. 首先是拷贝一个tomca ...
- 论 BUG调试与(程序猿)初学者
作为一枚程序猿,BUG调试是最基本的技能,对于初学者更是重中之重.个人而言,要想为自己的程序猿生涯更上一层楼,就得知道什么是BUG调试,而且还必须知道怎么调好BUG.那么BUG究竟是什么呢?在我之前的 ...