CF1920E 题解

本文介绍了如何通过动态规划解决一道关于序列划分的问题,关注子串贡献和合法序列的计算,特别是如何确定转移方程和p值的范围,以求解最长合法串长度不超过k的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

更好的阅读体验

CF1920E

被这种题卡了,脸都不要了。

仔细读题,发现序列可以分成两部分( 0 0 0 1 1 1)来考虑。

在合法序列中,对于一个 1 1 1,它产生的子串贡献一定是(假设与上一个 1 1 1 之间有 x x x 0 0 0,与下一个 1 1 1 之间有 y y y 0 0 0):
( x + 1 ) ( y + 1 ) (x+1)(y+1) (x+1)(y+1)

如果去 DP 这 n n

CF Directional Increase是一道经典的算法题目,通常出现在编程竞赛中。题目要求在一个二维网格中,找到从起点到终点的路径,使得路径上的数值递增。以下是详细的题解: ### 题目描述 给定一个二维网格,每个格子中有一个整数。起点在左上角,终点在右下角。你可以从当前格子移动到右边的格子或下边的格子。找到一条路径,使得路径上的数值递增。 ### 解题思路 1. **动态规划**:使用动态规划来解决问题。定义一个二维数组`dp[i][j]`,表示从起点到格子`(i, j)`的递增路径的长度。 2. **初始化**:起点`dp[0][0]`的值为`grid[0][0]`。 3. **状态转移方程**: - 如果从上方移动到当前格子`(i, j)`,则`dp[i][j] = max(dp[i][j], dp[i-1][j] + 1)`,前提是`grid[i][j] > grid[i-1][j]`。 - 如果从左方移动到当前格子`(i, j)`,则`dp[i][j] = max(dp[i][j], dp[i][j-1] + 1)`,前提是`grid[i][j] > grid[i][j-1]`。 ### 代码实现 ```python def directional_increase(grid): if not grid or not grid[0]: return 0 m, n = len(grid), len(grid[0]) dp = [[1] * n for _ in range(m)] for i in range(m): for j in range(n): if i > 0 and grid[i][j] > grid[i-1][j]: dp[i][j] = max(dp[i][j], dp[i-1][j] + 1) if j > 0 and grid[i][j] > grid[i][j-1]: dp[i][j] = max(dp[i][j], dp[i][j-1] + 1) return dp[m-1][n-1] # 示例 grid = [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ] print(directional_increase(grid)) # 输出: 5 ``` ### 解释 - 初始化`dp`数组为全1,因为每个格子的递增路径至少为1。 - 遍历每个格子,更新`dp[i][j]`的值。 - 最后,`dp[m-1][n-1]`即为从起点到终点的递增路径的最大长度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值