故地重游
去年连该写 spj 都不知道,毫不意外地挂大分了。今年重写这道题,把打的草稿放上来好了。
两条原则:把最后一个栈留空来应对各种情况;让 \(n-1\) 个栈的大小都不超过 \(2\)。
考虑加入一个数,
-
如果这个数在前面的栈里出现过了:
- 假如出现在栈顶,直接加入相应的栈进行消除。
- 假如出现在栈底,加入最后一个栈,然后用第二种方法消除。
-
如果这个数在前面的栈里没有出现过:
-
如果前 \(n-1\) 个栈还有没有到达 \(2\) 的栈,那么把这个数压入这个栈,不发生任何消除。
-
如果到这个数下一次出现都没有出现栈底的数,把这个数压入最后一个栈,直接操作到这个数下一次出现。
-
如果到这个数下一次出现之间出现了栈底的数,记栈底的数为 \(x\),它上面的数是 \(y\):
- 如果到 \(x\) 出现之前 \(y\) 出现了偶数次,那么可以把这个数压入 \(x,y\) 这个栈,后面遇到的 \(y\) 也都还是压入这个栈(会自己消掉),最后把 \(x\) 压入最后一个栈并进行第二种消除。
- 如果到 \(x\) 出现之前 \(y\) 出现了奇数次,那么可以把这个数压入最后一个栈,后面遇到的 \(y\) 也都还是压入 \(x,y\) 这个栈,\(x\) 也压入这个栈,然后 \(x,y\) 这个栈就空了。
-
所以为什么今年写的代码比去年补题时的代码长了 0.8K 呢?还是用了 lambda 表达式才比去年短。
去年连爆栈这种事情都没意识到,白白浪费了一个小时。
另外这题在洛谷上出现了蓝->紫->蓝->紫的反复横跳。但其实 DP 的部分应该不是很难才对(可能单拿出来只有绿?)。
本来想写写简要题解的,但是感觉没什么可解释的,咕了。