开题看到T1,直接放弃。(因为恶心的题目要求导致暴力很难写)然后看T2,一开始看到觉得很疑惑:输入数据呢???然后反复读了几遍题,才发现输入数据(或者说是需要的数据)是要自己手推的。反应还算快,主要是之前见过这个类型的题。
花了一点时间,想了一下。发现可以用 \(O(n)\) 的算法,但依旧会炸。\(n \le 1e9\)。结果,旁边的同学提醒了一下,说:“长度不一定为 \(k\) ,可以为\(k-n\)的任意一个数。”好家伙,直接放弃自己的想法,打起 \(O(n^2)\) 的暴力。虽然后面发现数据会出现循环节,但是依旧没有推出来。
看到后面的T3、T4,T3完全不会,一开始还以为是拓扑排序。主要是没有审好题目,如果看见了:
上菜的顺序只能是从 \(1-n\) 。
也许就会想到DP了。
最后干T4,用了 \(\text{map+BFS}\) 来干。一下子过了样例,自信满满的认为可以拿至少50分。
***,T4才10分,我还不如直接打表。
T2的20分是在我的预料之内的,毕竟是 \(O(n^2)\) 嘛。但是如果加一个预处理就可以AC了:n=min(n,4002)
。这是为什么?
T3居然又是多维dp,最近真的对dp感觉很不好,要不就是看不出来是dp,要不就是把题目误认为是dp,要不就是不会设状态、转移状态。但改题的时候又马上能听懂。
T1的插头+状压+轮廓线dp是个什么牛马?
这次没有抱着积极的心态去打比赛,更多是消极的。因为开始看到题目是在太难了。虽然后面老师过来说了一下,心态改变了一下,也想到了T2的循环节,但是已经晚了。
其他都还好,就是比赛的时候思路堵塞了,怎么想的想不出来。(建议学习Cold_Chair的上厕所大法,之前真的有用,有助于思考)
神奇的插头dp+状压dp+轮廓线dp。
是一个结论题。显然,循环节的最大长度是 \(2m+1\),然后一个循环节的值的和为0。所以我们要选择最少的循环节。\(k\) 以上的长度的最大值要不就是在一个循环节之内,要不就是两个循环节拼起来的一部分。所以我们只用求2个循环节,然后直接暴力。再看看数据范围:
\(m \le 1000\)
那么一个循环节的最长长度是 \(2m+1\),又因为至少需要两个循环节,所以就是 n=min(n,4002)
。
简单的四维dp题。设 \(f(i,j,k,l)\) 为:第1种菜选了前i个,第2种菜选了前j个,第三种菜选了前k个,当前最后一道菜是属于第l种菜的最小花费。
那么,分类讨论,分l是1、2、3的情况讨论。对于l=1的时候,我们只能从 \(f(i-1,j,k,1),f(i-1,j,k,2),f(i-1,j,k,3)\) 来转移。为什么是 \(i-1\) 呢?因为当前要取第一种菜的一个,且从开始到现在一共取了 前 \(i\) 个第一道菜,所以要 \(i-1\)。其余的转移方程显然,下面给出。
写在代码一共9个转移方程,细节还蛮多的,慢慢调吧。
显然如果单纯的搜索,无论什么搜索都不行。所以要用双向BFS。但是开始节点和最终的节点以及他们的后面的转移都放在一个队列里面。
然后就是判重的问题了。如果单纯hash,你会发现可以AC,但是特别烦,因为余数有相同的情况。所以要用康托展开优化。用康托展开+hash,那么每一个排列对应的数都是固定的,所以hash不会有很多余数相同出现。即使出现,也可以用拉链法等等方法。