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

  于是将强化牌和攻击牌各自从大到小排序。显然可以将其分开考虑。对强化牌,设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. C语言程序设计I—第十三周教学

    第十二周教学总结(26/11-01/12) 第十三周的教学总结在朋友圈发布了,没有及时在此更新,为了保持教学总结的完整性,现补齐. 今日学院有重大外事活动,所有老师停课参加并且不需要补课,但为了保证我 ...

  2. Centos7-kafka-2.12安装验证

    1.下载Kafka 官网:https://kafka.apache.org/ 2.安装脚本 #解压 tar zxf kafka_2.-.tgz -C /usr/local mv /usr/local/ ...

  3. go语言之行--接口(interface)、反射(reflect)详解

    一.interface简介 interface(接口)是golang最重要的特性之一,Interface类型可以定义一组方法,但是这些不需要实现.并且interface不能包含任何变量. 简单的说: ...

  4. MiZ702学习笔记10——文本实例化IP的方法

    之前,添加vivado自带IP的时候,都是以图形化的方式:一般是新建一个Block Design顶层文件,然后将图形化的ip贴到,Block Design中. 但是,在进行PL的开发过程中,有时不想使 ...

  5. CSS快速入门-前端布局1(抽屉)

    一.效果图 前面对CSS基础知识有了一定的了解,是时候开始实战了!以下我对抽屉(https://dig.chouti.com/)主页进行模拟布局. 官方网站效果图: 模拟网站图: 二.实现步骤 1.整 ...

  6. flask_admin 笔记四 自定义视图

    定义自己的视图 对于您的要求非常具体的情况,您很难用内置的ModelView类来满足这些需求,Flask-Admin使您可以轻松地完全控制并将自己的视图添加到界面中. 1)独立视图 可以通过扩展Bas ...

  7. Android——界面特效 相关知识总结贴

    帮助android UI实现动画特效 http://www.apkbus.com/android-79595-1-1.html 帮助android应用程序实现动画特效 http://www.apkbu ...

  8. vue基础项目安装教程

    安装node.js 从node.js官网下载并安装node,安装过程很简单,一路“下一步”就可以了. 安装完成之后,打开命令行工具,输入 node -v,如下图,如果出现相应的版本号,则说明安装成功. ...

  9. cadence allegro 封装原点修改

    打开 dra文件后 在菜单栏 setup - change drawing origin 在命令栏输入 新的参考点位置 如想更改新坐标位置为 1,2 .输入  x 1 2

  10. POJ 2431 (优先队列)

    题目链接:https://vjudge.net/problem/POJ-2431 思路: “ 在卡车行驶途中, 只有经过加油站才能加油.” 我们不妨转变思路, 理解成“当卡车驶过加油站时就获得了加油的 ...