BZOJ5467 PKUWC2018Slay the Spire(动态规划)
即求所有情况的最大伤害之和。容易发现应该先打强化牌,至少打一张攻击牌。同样显然的是强化牌和攻击牌都应该按从大到小的顺序打。进一步可以发现,只要还有强化牌,就应该使用(当然至少留一次攻击的机会)。
于是将强化牌和攻击牌各自从大到小排序。显然可以将其分开考虑。对强化牌,设f[i][j]为前i张牌抽到j张并打出的强化倍数之和,则显然有f[i][j]=f[i-1][j]+f[i-1][j-1]·w[i]。这样就搞定了强化牌可以打完的情况。同时设g[i]为抽i张打出k-1张的强化倍数之和,dp过程中通过f数组计算,注意避免重复。对于攻击牌也进行类似dp。然后枚举两种牌各抽了几张合并一下答案即可。注意细节。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 3010
#define P 998244353
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<''||c>'')) c=getchar();return c;}
int gcd(int n,int m){return m==?n:gcd(m,n%m);}
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
int T,n,m,k,a[N],b[N],f[][N][N],g[][N],C[N][N],h[N];
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj5467.in","r",stdin);
freopen("bzoj5467.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
T=read();
while (T--)
{
n=read(),m=read(),k=read();int lim=min(k-,n);
C[][]=;
for (int i=;i<=n;i++)
{
C[i][]=C[i][i]=;
for (int j=;j<n;j++)
C[i][j]=(C[i-][j-]+C[i-][j])%P;
}
memset(f,,sizeof(f));memset(g,,sizeof(g));memset(h,,sizeof(h));
for (int i=;i<=n;i++) a[i]=read();
for (int i=;i<=n;i++) b[i]=read();
sort(a+,a+n+),reverse(a+,a+n+);
sort(b+,b+n+),reverse(b+,b+n+);
f[][][]=;
for (int i=;i<=n;i++)
{
f[][i][]=;
for (int j=;j<=lim;j++)
f[][i][j]=(f[][i-][j]+1ll*f[][i-][j-]*a[i])%P;
if (lim==) for (int j=;j<=n;j++) g[][j]=C[n][j];
else
for (int j=lim;j<=n;j++)
g[][j]=(g[][j]+1ll*f[][i-][lim-]*a[i]%P*C[n-i][j-lim])%P;
}
for (int i=;i<=n;i++)
{
for (int j=;j<=m;j++)
f[][i][j]=(f[][i-][j]+f[][i-][j-]+1ll*b[i]*C[i-][j-])%P;
for (int j=m-k+;j<=n;j++)
g[][j]=(g[][j]+(f[][i-][j-(m-k)-]+1ll*b[i]*C[i-][j-(m-k)-])%P*C[n-i][m-k])%P;
}
for (int i=;i<=min(n,m);i++)
for (int j=;j<=n;j++)
h[i]=(h[i]+1ll*b[j]*C[n-j][i-])%P;
/*for (int i=0;i<=n;i++) cout<<f[0][n][i]<<' ';cout<<endl;
for (int i=0;i<=n;i++) cout<<g[0][i]<<' ';cout<<endl;
for (int i=0;i<=n;i++) cout<<f[1][n][i]<<' ';cout<<endl;
for (int i=0;i<=n;i++) cout<<g[1][i]<<' ';cout<<endl;
for (int i=0;i<=n;i++) cout<<h[i]<<' ';cout<<endl;*/
int ans=;
for (int i=max(,m-n);i<=min(n,m);i++)
if (i<=lim) ans=(ans+1ll*f[][n][i]*g[][m-i])%P;//抽了i张强化牌 全部出完 剩余m-i张攻击牌 选m-k张不出
else ans=(ans+1ll*g[][i]*h[m-i])%P;//抽了i张强化牌 选lim张出 剩余m-i张攻击牌 出1张
printf("%d\n",ans);
}
return ;
}
BZOJ5467 PKUWC2018Slay the Spire(动态规划)的更多相关文章
- [.NET] 打造一个很简单的文档转换器 - 使用组件 Spire.Office
打造一个很简单的文档转换器 - 使用组件 Spire.Office [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/6024827.html 序 之前,& ...
- 高效而稳定的企业级.NET Office 组件Spire(.NET组件介绍之二)
在项目开发中,尤其是企业的业务系统中,对文档的操作是非常多的,有时几乎给人一种错觉的是”这个系统似乎就是专门操作文档的“.毕竟现在的很多办公中大都是在PC端操作文档等软件,在这些庞大而繁重的业务中,单 ...
- [.NET] 开头不讲"Hello Word",读尽诗书也枉然 : Word 操作组件介绍 - Spire.Doc
开头不讲"Hello Word",读尽诗书也枉然 : Word 操作组件介绍 - Spire.Doc [博主]反骨仔 [原文地址]http://www.cnblogs.com/li ...
- 增强学习(三)----- MDP的动态规划解法
上一篇我们已经说到了,增强学习的目的就是求解马尔可夫决策过程(MDP)的最优策略,使其在任意初始状态下,都能获得最大的Vπ值.(本文不考虑非马尔可夫环境和不完全可观测马尔可夫决策过程(POMDP)中的 ...
- 简单动态规划-LeetCode198
题目:House Robber You are a professional robber planning to rob houses along a street. Each house has ...
- C#组件系列——又一款Excel处理神器Spire.XLS,你值得拥有(二)
前言:上篇 C#组件系列——又一款Excel处理神器Spire.XLS,你值得拥有 介绍了下组件的两个功能,说不上特色,但确实能解决我们项目中的一些实际问题,这两天继续研究了下这个组件,觉得有些功能用 ...
- C#组件系列——又一款Excel处理神器Spire.XLS,你值得拥有
前言:最近项目里面有一些对Excel操作的需求,博主想都没想,NPOI呗,简单.开源.免费,大家都喜欢!确实,对于一些简单的Excel导入.导出.合并单元格等,它都没啥太大的问题,但是这次的需求有两点 ...
- 动态规划 Dynamic Programming
March 26, 2013 作者:Hawstein 出处:http://hawstein.com/posts/dp-novice-to-advanced.html 声明:本文采用以下协议进行授权: ...
- 动态规划之最长公共子序列(LCS)
转自:http://segmentfault.com/blog/exploring/ LCS 问题描述 定义: 一个数列 S,如果分别是两个或多个已知数列的子序列,且是所有符合此条件序列中最长的,则 ...
随机推荐
- Scala--集合
一.主要的集合特质 Seq有先后顺序的序列,如数组列表.IndexedSeq通过下标快速的访问元素.不可变:Vector, Range, List 可变:ArrayBuffer, LinkedList ...
- FakeID签名漏洞分析及利用(一)
作者:申迪 转载请注明出处: http://blogs.360.cn/360mobile BlueBox于7月30日宣布安卓从2010年以来一直存在一个apk签名问题[1],并且会在今年Black ...
- Spring-data-jpa 学习笔记(二)
通过上一篇笔记的,我们掌握了SpringData的相关概念及简单的用法.但上一篇笔记主要讲的是Dao层接口直接继承Repository接口,然后再自己定义方法.主要阐述了自定义方法时的 ...
- Javascript 地图库收集
ArcGis leafletjs openlayers jvectormap
- 汇编 cdecl 函数调用约定,stdcall 函数调用约定
知识点: cdecl 函数调用约定 stdcall 函数调用约定 CALL堆栈平衡 配置属性--> c/c++ -->高级-->调用约定 一.cdecl调用约定 VC++ ...
- nginx location 正则匹配
nginx 统计语句1.根据访问IP统计UV awk '{print $1}' access.log|sort | uniq -c |wc -l2.统计访问URL统计PV awk '{print $7 ...
- 当activity改变时,我们如何处理它
用户和系统触发的事件,可能造成一个activity状体的改变.这个文档描述了一些常见的情况,和如何去处理这些改变. 原网站:https://developer.android.google.cn/g ...
- 利用十字链表压缩稀疏矩阵(c++)-- 数据结构
题目: 7-1 稀疏矩阵 (30 分) 如果一个矩阵中,0元素占据了矩阵的大部分,那么这个矩阵称为“稀疏矩阵”.对于稀疏矩阵,传统的二维数组存储方式,会使用大量的内存来存储0,从而浪费大量内存.为 ...
- DVWA渗透测试系列 一 (DVWA环境配置)
DVWA介绍: DVWA是一个渗透测试靶机系统. DVWA具有十个模块:分别是 Brute Force(暴力破解).Command Injection(命令行注入).CSRF(跨站请求伪造).File ...
- PAT甲题题解-1075. PAT Judge (25)-排序
相当于是模拟OJ评测,这里注意最后输出:1.那些所有提交结果都是-1的(即均未通过编译器的),或者从没有一次提交过的用户,不需要输出.2.提交结果为-1的题目,最后输出分数是03.某个题目从没有提交过 ...