【CSDN周赛第10期】比赛总结

这场运气不错,虽有事耽搁了一会儿,但四题都比较熟悉,顺利解出,拿到个人几场比赛中最好的名次,第一名。重要的是一直在进步。

1、题目名称:熊孩子拜访

已知存在一个长度为n的整数序列A。 A中所有元素按照从小到大的顺序进行排序。 现在执行操作倒置一段序列。 请找到A序列里的倒置子序列。
说明:
比如序列1 3 2 4,输出2 3分别是倒置子序列的左值和右值;
序列2 2 2 1 4,输出1 2;
序列1 2 3 4,输出0 0.

思路: 排序。序列A和排序后序列B比较,从左到右找到第一个元素不同和最后一个不同的位置,就是倒置子序列的左值和右值。也可以从左到右第一个不同的元素为左值,从右到左遍历第一个不同为右值。如果元素都相同,输出0 0。

2、题目名称:走楼梯

现在有一截楼梯,根据你的腿长,你一次能走 1 级或 2 级楼梯,已知你要走 n 级楼梯才能走到你的目的楼层,请实现一个方法,计算你走到目的楼层的方案数。
说明:
1 <= n <= 50

思路:斐波拉契数列。f(n) = f(n-1) + f(n-2)。用滚动数组的思想把空间复杂度优化到O(1)。
细节: 这题的n小于等于50,最后的方案数要用long表示。题目有点小陷阱,模板给的函数返回值是int,需手动改为long。然后通过率 80% -> 100%。

3、 题目名称:括号上色

小艺酱又得到了一堆括号。 括号是严格匹配的。 现在给括号进行上色。 上色有三个要求: 1、只有三种上色方案,不上色,上红色,上蓝色。 2、每对括号只有一个上色。 3、相邻的两个括号不能上相同的颜色,但是可以都不上色。 问括号上色有多少种方案?答案对1000000007取模。

这题来源CodeForces 149D,有难度。

说明:
(()), 输出12
()(()), 输出42

思路:
递归 + 记忆化搜索。
维护一个四维的状态数组dp[n][n][3][3] , 状态dp[i][j][m][n] 表示字符串第i位到第j位,i染m色,j染n色的方案数。不上色0,上红色1, 上蓝色2。
分情况讨论:

  1. i和j相邻(j-i == 1):
    dp[i][j][1][0] = 1
    dp[i][j][2][0] = 1
    dp[i][j][0][1] = 1
    dp[i][j][0][2] = 1

  2. 如果i和j位置的括号是匹配的:
    dp[i][j][1][0] += dp[i+1][j-1][m][n] (m!=1)
    dp[i][j][0][1] += dp[i+1][j-1][m][n] (n!=1)
    dp[i][j][2][0] += dp[i+1][j-1][m][n] (m!=2)
    dp[i][j][0][2] += dp[i+1][j-1][m][n] (n!=2)

  3. 如果i和j位置的括号不匹配, 匹配点为match[i]:
    dp[i][j][m][n] += dp[i][match[i]][m][x] * dp[match[i]+1][j][y][n] (m == n == 1 || m == n == 2 不成立)

细节: dp数组类型为long, 计算过程不断取模,防止long溢出。

4. 题目名称:青蛙过河

总是喜欢在水里嬉戏的青蛙,某天要过河拜访一位朋友。
已知河道中长满了带刺的不知名生物,能通过的路只有一条直线,长度为L。
直线上随机分布着m块石头。青蛙的最小跳跃距离是s,最大跳跃距离是t。
青蛙想要尽可能的少踩石头,那么它通过河道最少会踩到多少石头?

说明:
(1 <= L <= 10^9)
(1 <= s <= t <= 10,1 <= m <= 100)
10
2 3 5
2 3 5 6 7

题目来源:Vijos1002 , 有难度。

思路:
离散化动态规划
对于特判, s == t, 计算有多少个石头在s的倍数位置上。
对于 s != t
排序石头数组。
状态的转移不难想到,一个状态由其前(t-s+1)个状态递推得到,由于L特别大,直接开10^9的数组,内存会超出,实际上dp数组长度为 t 即可,然后滚动数组。同时,L过大也会导致超时,我们发现,石头最多100个,当两个石头间距大于一定值时,在一段没有石头的空白区间,dp状态无变化,因此想办法去掉空档区间,缩短遍历时间。

你可能感兴趣的:(算法,CSDN竞赛)