原比赛链接
T1:
考场思路:
原来是暴力模拟,只枚举偶数位的棋子,指针往前移动修改。
后来想到用线段树优化,但是要进行大量的单点查询,所以比原算法还要慢。
正解:
我们可以开三个栈,记录左边界,右边界以及连续的值,最后再将连续区间合并即可,时间复杂度是线性的。
T2:
考场思路:
暴力枚举字符串
1
1
1的所有子字符串,然后利用判断子串的方式判断其是否为字符串
2
2
2的子字符串,更新即可。
时间复杂度达到了
n
3
n^3
n3
正解:
动态规划,方程
f
[
i
,
j
]
=
[
S
1
[
i
]
=
S
2
[
j
]
]
⋅
(
f
[
i
−
1
,
j
−
1
]
)
f[i,j]=\big[S_1[i]=S_2[j]\big]\cdot(f[i-1,j-1])
f[i,j]=[S1[i]=S2[j]]⋅(f[i−1,j−1])
最后的答案为
max
1
≤
i
,
j
≤
n
{
f
[
i
,
j
]
}
\max\limits_{1\le i,j\le n}\{f[i,j]\}
1≤i,j≤nmax{f[i,j]}
T3:
考场想到了正解,但是由于文抄打错被hack了。
正解:
- 我们可以预处理出由零个数,一个数,两个数组和成的情况,排序。
- 设定两个指针 i , j i,j i,j一个代表指向较大数的指针,一个代表较小数的指针。
- 若相加得和大于 M M M,则较大指针前移,否则对 a n s ans ans取 max \max max然后较小指针前移。
T4:
考场上也想到了正解。
正解:
设
f
[
i
,
j
,
k
]
f[i,j,k]
f[i,j,k]表示移动到第
i
i
i行的第
j
j
j个石头,用了
k
k
k次快速跳跃的最少危险系数。
现在来说说状态转移:
- 对于 i = 1 i=1 i=1, f [ i , j , k ] = 0 f[i,j,k]=0 f[i,j,k]=0
- 对于 i = 2 i=2 i=2,显然只能通过由第一行进行普通跳跃转移。
- 对于
i
≥
3
i≥3
i≥3,可以通过前一行普通跳跃转移,也可以通过前两行快速跳跃转移,此时的转移方程为:
f [ i , j , k ] = min { min 1 ≤ l ≤ K [ i − 1 ] { f [ i − 1 ] [ l ] [ k ] } 普通跳跃转移 min 1 ≤ l ≤ K [ i − 2 ] { f [ i − 2 ] [ l ] [ k − 1 ] } 快速跳跃转移 f[i,j,k]=\min\begin{cases}\min\limits_{1\le l\le K[i-1]}\{f[i-1][l][k]\}&\text{普通跳跃转移}\\\min\limits_{1\le l\le K[i-2]}\{f[i-2][l][k-1]\}&\text{快速跳跃转移}\end{cases} f[i,j,k]=min⎩⎨⎧1≤l≤K[i−1]min{f[i−1][l][k]}1≤l≤K[i−2]min{f[i−2][l][k−1]}普通跳跃转移快速跳跃转移