即求所有情况的最大伤害之和。容易发现应该先打强化牌,至少打一张攻击牌。同样显然的是强化牌和攻击牌都应该按从大到小的顺序打。进一步可以发现,只要还有强化牌,就应该使用(当然至少留一次攻击的机会)。

  于是将强化牌和攻击牌各自从大到小排序。显然可以将其分开考虑。对强化牌,设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(动态规划)的更多相关文章

  1. [.NET] 打造一个很简单的文档转换器 - 使用组件 Spire.Office

    打造一个很简单的文档转换器 - 使用组件 Spire.Office [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/6024827.html 序 之前,& ...

  2. 高效而稳定的企业级.NET Office 组件Spire(.NET组件介绍之二)

    在项目开发中,尤其是企业的业务系统中,对文档的操作是非常多的,有时几乎给人一种错觉的是”这个系统似乎就是专门操作文档的“.毕竟现在的很多办公中大都是在PC端操作文档等软件,在这些庞大而繁重的业务中,单 ...

  3. [.NET] 开头不讲"Hello Word",读尽诗书也枉然 : Word 操作组件介绍 - Spire.Doc

    开头不讲"Hello Word",读尽诗书也枉然 : Word 操作组件介绍 - Spire.Doc [博主]反骨仔 [原文地址]http://www.cnblogs.com/li ...

  4. 增强学习(三)----- MDP的动态规划解法

    上一篇我们已经说到了,增强学习的目的就是求解马尔可夫决策过程(MDP)的最优策略,使其在任意初始状态下,都能获得最大的Vπ值.(本文不考虑非马尔可夫环境和不完全可观测马尔可夫决策过程(POMDP)中的 ...

  5. 简单动态规划-LeetCode198

    题目:House Robber You are a professional robber planning to rob houses along a street. Each house has ...

  6. C#组件系列——又一款Excel处理神器Spire.XLS,你值得拥有(二)

    前言:上篇 C#组件系列——又一款Excel处理神器Spire.XLS,你值得拥有 介绍了下组件的两个功能,说不上特色,但确实能解决我们项目中的一些实际问题,这两天继续研究了下这个组件,觉得有些功能用 ...

  7. C#组件系列——又一款Excel处理神器Spire.XLS,你值得拥有

    前言:最近项目里面有一些对Excel操作的需求,博主想都没想,NPOI呗,简单.开源.免费,大家都喜欢!确实,对于一些简单的Excel导入.导出.合并单元格等,它都没啥太大的问题,但是这次的需求有两点 ...

  8. 动态规划 Dynamic Programming

    March 26, 2013 作者:Hawstein 出处:http://hawstein.com/posts/dp-novice-to-advanced.html 声明:本文采用以下协议进行授权: ...

  9. 动态规划之最长公共子序列(LCS)

    转自:http://segmentfault.com/blog/exploring/ LCS 问题描述 定义: 一个数列 S,如果分别是两个或多个已知数列的子序列,且是所有符合此条件序列中最长的,则 ...

随机推荐

  1. vxlan 简单理解 vs calico 网络模型

    1.vxlan(virtual Extensible LAN)虚拟可扩展局域网,是一种overlay的网络技术,使用MAC in UDP的方法进 行封装,共50字节的封装报文头. 2.VTEP为虚拟机 ...

  2. day72

    今日内容: 1 创建多表模型(详情见代码) from django.db import models # Create your models here. class Publish(models.M ...

  3. Controller中添加一个异步的Action

    给一段示例代码: public Task<ActionResult> TbReport(string code) { return Task.Factory.StartNew(() =&g ...

  4. rpm yum apt-get redhat centos ubuntu

    rpm是由红帽公司开发的软件包管理方式,使用rpm我们可以方便的进行软件的安装.查询.卸载.升级等工作.但是rpm软件包之间的依赖性问题往往会很繁琐,尤其是软件由多个rpm包组成时.Yum(全称为 Y ...

  5. Iframe和Frame中实现cookie跨域的方法(转载)

    在Iframe和Frame中默认是不支持Cookie跨域的,但通过设置P3P协议相关的响应头可以解决这一问题.关于p3p协议: P3P: Platform for Privacy Preference ...

  6. RTSP server 在mips 上莫名其妙退出(PC上则无此问题)

    http://blog.csdn.net/lubing20044793/article/details/38523701 早在这篇blog以前写过,在虚拟机下调试sn9c291时,USB 数据传输出了 ...

  7. WPF XML序列化保存数据 支持Datagrid 显示/编辑/添加/删除数据

    XML序列化保存数据 using System; using System.Collections.Generic; using System.Linq; using System.Text; usi ...

  8. 【转】从Shell脚本内部将所有标准输出及标准错误显示在屏幕并同时写入文件的方法

    如果全部都要重定向的话每一条命令后面>>并不方便,可以这么做.在开头就声明 exec 1>>$log_file表示将脚本中所有的正确输出全部追加到$log_file,错误信息会 ...

  9. [CF1060F]Shrinking Tree[树dp+组合计数]

    题意 你有一棵 \(n\) 个点的树,每次会随机选择树上的一条边,将两个端点 \(u,v\) 合并,新编号随机为 \(u,v\).问最后保留的编号分别为 \(1\) 到 \(n\) 的概率. \(n\ ...

  10. HashMap 源码解析(一)之使用、构造以及计算容量

    目录 简介 集合和映射 HashMap 特点 使用 构造 相关属性 构造方法 tableSizeFor 函数 一般的算法(效率低, 不值得借鉴) tableSizeFor 函数算法 效率比较 tabl ...