USACO 2018 February Gold 题解
概述
上次一月因为准备期末考试太忙而放弃,到了二月里的寒假就有时间做金组了。这次在我看来有两题数据结构,然而题解并非如此。我感觉比前几个月的金组简单多了。
此前的2017年十二月的月赛我从铜组升到金组,题解以后有兴趣考虑吧。
Snow Boots
大意
一条路上有$N$个格子编号$1 \dots N$,第$i$格有一定的深度的雪$f_i$,$1$和$N$都没有雪。有$B$双鞋,穿每双鞋最多能在$s_i$的雪中,每步最多走$d_i$格,求每双鞋是否能从$1$走到$N$。$1\le N,B\le 100,000$
样例
1 | 8 7 |
1 | 0 |
思路
可以每次$\mathcal O(N)$判断是否可行,复杂度$\mathcal O(BN)$。
考虑离线处理,将询问按照$s_i$排序,按照深度依次加入格子,用一个std::set
维护,初始时只加入$1$和$N$。为了得到答案,还需要用堆维护最大的间隔,为了支持删除用std::set
更方便,具体用two-pointers实现。视$\mathcal O(B)=\mathcal O(N)$,则复杂度$\mathcal O(N\log N)$。
换一种思维,考虑先加入所有格子,然后逐个删除。这样就简单很多了,不再需要大常数的std::set
,只要一个双向链表即可,空隙一定是单调增的,用一个变量维护即可。这是官方题解的方法,简单很多。
查看代码
1 |
|
Directory Traversal
大意
有一个文件系统,求选定一个目录,使得表示所有文件相对路径的字符串长度和的最小。输入以邻接表形式输入。$N\le 100,000$
样例
1 | 8 |
1 | 42 |
最优情况选择folder1
,相对路径为:
1 | file1 |
思路
文件系统是标准的树,只不过向下和向上的边权不同,向下为文件名长度+1,向上为3(…/)。我的简单想法是先选择根目录,得到每个文件的长度,然后再次dfs,向下走把子树内的长度减去文件名长度+1,子树外的加上3,更新最优解。这样求dfs序,再用线段树维护即可,时间复杂度$\mathcal O(N\log N)$。
更加简单的方法应该是树形DP,复杂度线性,但是暂时没有官方题解。
查看代码
1 |
|
Taming the Herd
大意
有一个计数器,每天如果发生事件则清零,否则加一。把连续$N$天的结果记录下来,但可能被篡改,其中第一天一定发生事件,求$\forall i\in 1\dots N$,若发生$i$次事件,则至少有几天被篡改。$N\le 100$
样例
1 | 6 |
1 | 4 |
事件次数 | 最优序列 | 差异 |
---|---|---|
1 | 0 1 2 3 4 5 | 4 |
2 | 0 1 2 3 0 1 | 2 |
3 | 0 1 2 0 0 1 | 1 |
以此类推
思路
在fks的提醒下,这其实是简单的DP。用$f[i][j][k]$表示前$i$天,发生$j$次事件,计数器的值为$k$最少篡改次数。则有初始条件
$$f[1][1][0]=\begin{cases}0 & a[1]=0 \ 1 & \text{otherwise}\end{cases}$$
第$i+1$天的决策为
$$f[i+1][j][k+1]=\min f[i][j][k]+\begin{cases}0 & a[i+1]=k+1 \ 1 & \text{otherwise}\end{cases}$$
$$f[i+1][j+1][0]=\min f[i][j][k]+\begin{cases}0 & a[i+1]=0 \ 1 & \text{otherwise}\end{cases}$$
目标状态为
$$\min_{k\in 1\dots n} f[n][j][k]$$
复杂度$\mathcal O(N^3)$
查看代码
1 |
|