NOI模拟赛 6.15
赛时时间安排
7:20-7:40 读题面
阅读题面,准备从T1做起
7:40-8:20 想T1算法
一开始没什么状压的思路,后来根据数据范围猜了个复杂度\(O(cm\times 3^m\times n\times else)\)。
猜的理由:
①\(cm\)是因为这题求期望,但期望对应的价值的范围为\([0,cm=30]\),非常小,应该可以枚举
②\(3^m\)是因为这题肯定要状压,而只有\(m(m\leq 10)\)能用来状压,但\(2^m=1024\)又太小了,于是估计是\(3^m\)枚举子集
③\(n\)在复杂度里还没出现,可以枚举
④这样乘起来已经到\(\mathtt{70,858,800}\)了,但\(cm\)跑的很不满,肯定还要乘个啥
于是根据复杂度的提示又开始想算法,发现如果状压\(m\)并枚举子集的话,一个\(n\)的贡献可以以子集的形式一次性加入,于是确定下来最外层枚举\(n\)(类似背包),然后依次枚举操作集合、价值上线、子集、子集的价值上限,最后转移。此时也确定下来总的复杂度为\(O((cm)^2\times 3^m\times n)\)
8:20-9:10 码T1
码T1,发现这个状压的过程细节很多,需要时刻小心确保没有重复转移,很不好码,为了求出转移时单个\(n\)的概率方便转移,又设计了一个\(O(n\times 2^m \times c^2m)\)的DP来预处理出单个转移时单个\(n\)的概率。
9:10-10:55 调T1
码完后陷入了痛苦的调试过程中,对着一大堆求逆元后的数字进行调试非常自闭,期间修改了很多细节错误,需要特意点出的两点错误:
①涉及背包类DP转移时最好为了防止因转移顺序出错,最后还是另外设置临时的转移数组
②取模时为了防止因漏取模而WA/浪费调试时间,最后还是通过宏定义的方式取模
10:55-11:30 码T2暴力、检查
没多少时间了,敲了个T2的暴力上去,检查了检查文件名、空间,就交了
赛后总结反思
1.T1调试过程出现的两处错误
①涉及背包类DP转移时最好为了防止因转移顺序出错,最后还是另外设置临时的转移数组
②取模时为了防止因漏取模而WA/浪费调试时间,最后还是通过宏定义的方式取模
2.状压类问题数据规模
这段时间新学了不少状压类问题的处理技巧,在这里总结一下
数据规模 | 常见类型 | 例题 |
---|---|---|
\(n\leq 46\) | 折半搜索 | P6962 [NEERC2017]Knapsack Cryptosystem |
\(n\leq 20\) | 普通状压 | - |
\(n\leq 20\) | 高维前缀和(FWT/FMT) | P5643 [PKUWC2018]随机游走 |
\(n\leq 14\sim16,m\leq 10^2\sim10^3\) | DP套DP | P4590 [TJOI2018]游园会、LOJ6274 数字 |
\(n\leq 15\) | 子集枚举 | 6.15 Max |
\(n\leq 15\) | 三进制状压 | 6.11 arg、LOJ10172 「一本通 5.4 练习 1」涂抹果酱 |
\(n\leq10\) | DP数组两维均为集合的状压 | CF53E Dead Ends |
3.时间安排
在发现T1代码较难实现时应该先花一些时间把T2、T3的低档暴力打掉,保证基础分数