#0013.「Codeforces」1354F Summoning Minions

Posted myrcella

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了#0013.「Codeforces」1354F Summoning Minions相关的知识,希望对你有一定的参考价值。

题目大意:

  n个小黄人!每个小黄人有初始战斗值a和另一个值b。每次召唤一个小黄人i可以使前面召唤的所有小黄人战斗值加bi。每个小黄人可以被雇佣和解雇任意一次。需要保证任意情况下队伍内小黄人的数量不超过m。输出任意一个最优的操作序列。

  m<=n<=75

  多测,T<=75

题目解法: 

  (好喜欢这道题www

  首先看到这种题的第一反应就是排序后dp。

  观察1:最后的操作序列一定是 雇佣(m-1)个+雇佣后解雇(n-m)个+雇佣1个

  因为我们最后只有m个小黄人在队伍中,显然有n-m个是无法雇佣的。对于这n-m个小黄人,他们的贡献显然只有b的加成。所以显然我们要让这样的操作尽可能后。为了保证随时不超过m个小黄人,显然我们只能采取上述操作。

  //这个观察使我们在dp中对于每个小黄人有 最终雇佣 和 雇佣后被解雇掉 两种转移方法。

  观察2:最终雇佣的m个小黄人b值一定递增。

  a值直接求和和顺序无关显然。而b值的贡献显然是和顺序有关的。越往后雇佣的可以给更多的小黄人加战斗值,所以显然按b值递增处理最优。

  观察3:不在最终队伍中的小黄人都对答案贡献(m-1)*bi


 

  综上所述,我们可以得到一种有效的算法:

  先将所有小黄人按b升序排列。

  f(i,j)表示考虑前i个小黄人有j个在最终队伍里的最大战斗力。

  f(i,j)=max{f(i-1,j)+(m-1)*bi, f(i-1,j-1)+(j-1)*ai},再用一个数组记录每个f(i,j)是从f(i-1,j)还是f(i-1,j-1)转移过来的。这样就可以得到最大战斗值了。

  复杂度O(T*n*m)

  

以上是关于#0013.「Codeforces」1354F Summoning Minions的主要内容,如果未能解决你的问题,请参考以下文章

0013 罗马数字转整数

0012-0013.博客园

第十一周PSP&进度条

Unity NGUI的Anchors编程

20160203.CCPP体系详解(0013天)

计算机组成原理0013