• 「刷题」可怜与STS


    又是一道假期望,我们发现一共有$ C_{2n}^m $种情况。

    而$ frac{(2n)!}{m!(2n-m)!}=C_{2n}^m $

    其实结果就是各个情况总伤害。

    1.10分算法,爆搜10分。

    2.30分算法,发现20%的攻击牌数值相同,这样先强化后攻击(至少留一张攻击牌)是最优策略。计算拿到$i$张强化牌,最小是第$j$张的情况下强化乘积和,乘上攻击牌的大小即可。

    3.50分算法,发现20%的$m==k$,这样不用考虑出牌策略,先强化后攻击即可,分别计算拿到$i$张强化牌,最小是第$j$张的情况下的强化乘积和以及拿到$i$张攻击牌,最小是第j张的情况下的攻击和。两部分分别相乘即可。

    4.$AC$算法,考虑最优策略的通解。发现每张强化牌至少会让所有的攻击牌数值翻倍,那么如果我选择只打最大的一张攻击牌的话,即使被一张最小的强化牌占据一张出牌机会,也能够让最大的一张翻倍,这样贡献要大于打一张最大的攻击牌和一张第二大的攻击牌。也就是说对于每个位置,最小的强化牌的贡献都要大于第二大的攻击牌,那么最优策略就是,只打最大的一张攻击牌,剩下的位置留给强化牌从大到小打,最后打出这张攻击牌,这样的伤害是最大的。

    有了这个决策之后,我们不妨$sort$牌组。

    设$f[i][j]$为强化牌选了$i$张,最后一张也是最小一张选的是第$j$张牌的乘积和,$g[i][j]$为攻击牌选了$i$张,最后一张也是最小的一张选的是第j张牌的攻击和,$a_i$是第$i$张强化牌,$b_i$是第$i$张攻击牌。

    初始化:$f[0][0]=1$;

    方程:

      $ f[i][j]=a_isum limits_{k=1}^{j-1} f[i-1][k] $

      $ g[i][j]=b_i C_{j-1}^{i-1} sum limits_{k=1}^{j-1} g[i-1][k] $

    组合数的意思是之前有这么多种情况($j-1$张牌中选$i-1$张牌,每种情况转移到$g[i][j]$中都需要加上一个$b_i$),前缀和优化,是$ O(n^2) $

    设$F[i][j]$为选$i$张强化牌,打出$j$张强化牌的乘积和,$G[i][j]$为选$i$张攻击牌,打出$j$张攻击牌的伤害和。

    方程:

      $ F[i][j]=sum limits_{k=j}^n f[j][k] C_{n-k}^{i-j} $

      $ G[i][j]=sum limits_{k=j}^n g[j][k] C_{n-k}^{i-j} $

    组合数的意思是这j张牌是我打出去的大牌,那么剩下的$ i-j $张必定不如之前的$ j $张优,也就是小于$ k $,而小于k的牌一共有$ n-k $张。

    这样发现是$ O(n^3) $的,时间上无法承受,在观察答案。

    我们要求的:

        $ ans=sum limits_{i=0}^{min(m-1,n)} F[i][min(i,k-1)] G[m-i][max(1,k-i)] $

    这是根据最优策略制定的,也就是说$i$张强化牌做多打出$k-1$张,而$m-i$张攻击牌最少要打出一张。

    我们发现函数$F$和函数$G$都取单点值,所以只需要计算最多$m$个值。

    那么$F$和$G$的计算复杂度仍然是$ O(n^2) $

    总的时间复杂度:$ O(Tn^2) $

    问题得解。

  • 相关阅读:
    IO流图片加密。
    IO流(流的标准处理异常代码)
    字节流写出中文。
    字节流读取中文。
    IO流BufferedInputStream和BufferOutputStream拷贝。
    Collection集合。
    《C#并发编程经典实例》学习笔记—2.3 报告任务
    《C#并发编程经典实例》学习笔记—2.2 返回完成的任务
    《C#并发编程经典实例》学习笔记—2.1 暂停一段时间
    《C#并发编程经典实例》学习笔记—异步编程关键字 Async和Await
  • 原文地址:https://www.cnblogs.com/Lrefrain/p/11234687.html
Copyright © 2020-2023  润新知