这次考试不是很难,但是我只考了 268.3 268.3 268.3分,原因出在第三题。
这道题目我们直接搜索即可。
首先将输入的字符排序。
然后暴力搜索(类似全排列)就行了。
注意:到了 25000 25000 25000个之后要关闭程序。
满分。
这道题目我们开一个 1000000 1000000 1000000的数组。
然后直接深搜即可。
每一次有一个新的数,答案就加一。
满分。
就是求联通块的最大大小。
直接对于每一个没有标记的点进行 d f s dfs dfs,并遇到一个新的点就标记和答案加一。
时间复杂度为 O ( n 2 ) O(n^2) O(n2)。
58.3 58.3 58.3分。
设 f i , j f_{i,j} fi,j表示前 i i i种类型的蚂蚁用了 j j j个的方案数。
则
f i , j = ∑ k = 0 n i f i − 1 , j − k \begin{aligned}f_{i,j}=\sum_{k=0}^{n_i}{f_{i-1,j-k}}\end{aligned} fi,j=k=0∑nifi−1,j−k
但是由于 j j j可能小于 n i n_i ni,所以 f i , j = ∑ k = 0 m i n ( n i , j ) f i − 1 , j − k \begin{aligned}f_{i,j}=\sum_{k=0}^{min(n_i,j)}{f_{i-1,j-k}}\end{aligned} fi,j=k=0∑min(ni,j)fi−1,j−k。
我们发现这种算法是 O ( T × ∑ i = 1 A n i ) \begin{aligned}O(T\times{\sum_{i=1}^{A}{n_i}})\end{aligned} O(T×i=1∑Ani)。
数据很水,可以过掉。
最优方法是进行前缀和优化。
设 s i , j s_{i,j} si,j表示前 i i i种类型的蚂蚁用了 0 − j 0-j 0−j个的方案数之和。
也就是 s i , j = ∑ k = 0 j f i , k \begin{aligned}s_{i,j}=\sum_{k=0}^{j}{f_{i,k}}\end{aligned} si,j=k=0∑jfi,k。
运用前缀和优化可得 s i , j = s i , j − 1 + f i , j s_{i,j}=s_{i,j-1}+f_{i,j} si,j=si,j−1+fi,j。
根据上面这条式子: f i , j = ∑ k = 0 m i n ( n i , j ) f i − 1 , j − k \begin{aligned}f_{i,j}=\sum_{k=0}^{min(n_i,j)}{f_{i-1,j-k}}\end{aligned} fi,j=k=0∑min(ni,j)fi−1,j−k。
因为是求从 j − m i n ( n i , j ) j-min(n_i,j) j−min(ni,j)到 j j j的 f f f的第 i i i项的和,所以
f i , j = s i − 1 , j − s i − 1 , j − m i n ( n i , j ) − 1 f_{i,j}=s_{i-1,j}-s_{i-1,j-min(n_i,j)-1} fi,j=si−1,j−si−1,j−min(ni,j)−1
由此,我们得出了求 s i , j s_{i,j} si,j和 f i , j f_{i,j} fi,j的公式,可以解决此问题。
时间复杂度降为 O ( A T ) O(AT) O(AT)。
10 10 10分。