码迷,mamicode.com
首页 > 其他好文 > 详细

【比赛】【NHOI 2019】

时间:2019-08-01 11:43:44      阅读:183      评论:0      收藏:0      [点我收藏+]

标签:数据   细节   决策   paste   个数   dfs   表示   单调队列   思路   

生动展示了自己有多菜

从T4开始


\(\mathrm{T4}\)

对于新给出的货币值\(New\),我们先求出\(l=\mathrm{lcm}(New,50000)\),那么,对于所要凑出的货币值\(N\),问题就分解成了两部分:

  • 对于\(\dfrac{N}{l}\)的部分,答案就是\(\dfrac{l}{\max(New,50000)}\)

  • 对于\(N \bmod l\)的部分,就可以直接用\(\mathrm{dfs}\)做。

    \(\mathrm{dfs}\)很简单(两个决策):

    1. 如果当前货币数\(x\)小于\(New\),则返回\(\mathrm{val}(x)\)(就是直接用原来的货币凑成指定钱数的最少纸币数)

    2. 如果大于\(New\),则取一个\(\min\)
      • \(\mathrm{val}(x)\)
      • \(\mathrm{dfs}(x-New)+1\)(表示用了一张\(New\)

\(\mathrm{Code}\)


\(\mathrm{T5}\)

这一题感觉很玄……

本质上就是一直找数量最多的那一种袜子去减……

\(\mathrm{Code}\)


\(\mathrm{T6}\)

地狱模式开启

  • 考虑一个\(DP\):用\(f(i,S)\)表示将前\(i\)个珠宝当中其颜色在集合\(S\)中出现过的珠宝排好所需的最少移动次数。

    显然,对于每一个\(i\),我们就考虑一个比\(i\)小的位置\(j\),然后再枚举一种颜色\(c\),将\([1,j)\)这个区间里面颜色是\(c\)的珠宝移到\([i,j]\)里面,再将\([i,j]\)当中颜色不是\(c\)的珠宝都移走。

    这样,状态转移方程就已经出炉了:

    \[f(i,S)=\min \{ f(j,S-\{c\} )+csum(1 \sim j-1,\{c\})+csum(j\sim i,S-\{c\}) \}\]

    (这里用\(\sim\)的形式代替了前缀和,\(csum\)表示的是各个颜色集合的前缀和)

    最终的答案就是\(f(n,2^m-1)\)

    这个\(DP\)的时间复杂度是\(O(n^2\times 2^m \times m)\),可以捞到\(94\ pts\)

    (原本没什么问题的,但是不知道为什么要把颜色都离散化了才能过……)

    \(\mathrm{Code}\)

  • 继续优化并不太难,我们把上面的状态转移方程用前缀和的形式写出来:

    \[f(i,S)=\min \{ f(j,S-\{c\} )+csum(j-1,\{c\})+csum(i,S-\{c\})-csum(j-1,S-\{c\}) \}\]

    把关于\(j\)的部分提出来:

    \[\min \{ f(j,S-\{c\} )+csum(j-1,\{c\})-csum(j-1,S-\{c\}) \}\]

    就会发现这个\(DP\)的转移具有单调性,又因为\(S\)\(c\)也会影响转移,所以我们可以用一个数组\(Min(S,c)\)来表示到当前位置关于\(S,c\)的最佳决策。

    因为\(j\)最大可以等于\(i\),所以对于第\(i\)个位置,我们应该先维护\(DP\)本身,再把\(i\)这个位置的各个\(csum\)\(f\)加入单调队列。

    因为有了单调队列,所以不需要再枚举\(j\),时间复杂度降为\(O(n\times 2^m\times m)\),可以通过此题。

    \(\mathrm{Code}\)

  • 然而,人民公敌\(lgj\)加大了数据,\(n\)变成了\(10^3\)

    这……怎么办?

    思路就是要反过来,用记忆化搜索

    还是用\(f(i,S)\),但是\(i\)指的是\(i\)个珠宝

    转移不是很难想:

    • 如果\(c(i)\)这个颜色在\(S\)没有出现,则直接转移到\(f(i+1,S)\)
    • 如果出现了,则分情况考虑。
      • 要不我就把第\(i\)个珠宝扔到后面的某个位置,这样就可以转移到\(f(i+1,S)+1\)(因为扔一个只需要移一次)
      • 要不我就再枚举一个\(j\)(像之前枚举\(j\)一样),将\([i,j]\)中不是\(c(i)\)的移出去,将\((j,n]\)中是\(c(i)\)的移进来。这样就转移到了\(f(i+1,S-\{c\})+csum\)(这里因为懒把\(csum\)的细节省略了)

    在没有任何优化的情况下,这个\(DP\)的时间复杂度就已经是\(O(n^2\times 2^m)\)的了(因为不需要再去枚举颜色)

    但是,优化还是有的,答题思路还是和之前的一样,将和\(j\)有关的东西拉出来塞进单调队列里。

    但是有重点!!!

    一定要在转移了\(f(i+1,S)+1\)之后,再转移单调队列!

    如果先转移了单调队列的话,单调队列的结果就会影响到\(f(i+1,S)\)!但\(i\)这个位置的决策不能影响\(i+1\)的决策!

    当然还有一些细节,比如说可以维护一个链表,使得\(DP\)时可以快速找到下一个同一颜色的珠宝的位置,这些是后话了。

    \(\mathrm{Code}\)

    (神tm代码竟然越 来 越 短

【比赛】【NHOI 2019】

标签:数据   细节   决策   paste   个数   dfs   表示   单调队列   思路   

原文地址:https://www.cnblogs.com/info---tion/p/11281452.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!