1 不完美字符串问题

对于一个长度为 的仅由 构成的字符串 ,其不完美度定义为所有相邻字符对中互不相同的字符对数量的和。比如,长度为 的字符串 “” 的不完美度为 ,这是由 两个相邻数对贡献得到的。形式化地,字符串 的不完美度如下式:

(运算的结果取决于其中布尔表达式的真值。若为假,其值为 ,若为真,其值为 )

现给定一个长度为 的字符串 ,每一位仅由 组成。你需要将其中的每一个 替换成 或者 ,且最小化字符串 的不完美度

例如,给定的字符串为 “”,一种使不完美度最小的替换方案为 “”,其不完美度为 ,可以证明,没有其他替换方案,请使用动态规划算法求解最小的不完美度,并给出一个替换方案。请描述算法的核心思想,给出算法伪代码并分析其对应的时间复杂度。

  • 分析:本问题可以使用动态规划的方法求解,对于长度为 的字符串的第 个字符,其与前 个字符组成的字符串之间的关系会决定前 个字符组成的字符串的不完美度与前 个字符组成的字符串的不完美度间的关系。当 时, ;当 时, 。替换 获得最小不完美度字符串时,当 位于最左侧时,其应与右侧字符相同;当 位于最右侧时,其应与左侧字符相同;当 位于两字符之间时,若两字符相同,则其应与左侧字符相同,若两字符不相同,则其不完美度增量至少为 ,其也应与左侧字符相同。综上,可以获得替换方案:当 左侧有字符时,其应与左侧字符相同;当 左侧没有字符时,其应与右侧字符相同。如果右侧是 字符,则应与第一个非 字符相同。
  • 时间复杂度:
  • 伪代码:q1

2 鲜花组合问题

花店共有 种不同颜色的花,其中第 种库存有 枝,现要从中选出 枝花组成一束鲜花。请设计算法计算有多少种组合一束花的方案,请描述算法的核心思想,给出算法伪代码并分析其对应的时间复杂度。(两种方案不同当且仅当存在一个花的种类 ,两种方案中第 种花的数量不同)

  • 分析:这是一个组合问题,具有最优子结构的特点。在这个问题中,每个问题可以化为子问题。当备选花有 种,要选择 枝时,可以得到方案数结果为 ,则当备选花为 种时,就可以在此基础上进行进一步状态转移。当这 枝花都不选第 种时,其方案数与 相等;当这 枝花选一枝第 种花时,其方案数与 相等;以此类推,直至这 枝花都选第 种花,此时方案数即为 。所以即可得到 ,计算即可获得结果。应当指出,当 时,前式不成立,而是 成立。

  • 时间复杂度:

  • 伪代码:q2

3 最长公共上升子序列问题

对两个序列 ,序列 的公共上升子序列,当且仅当 的公共子序列,且 是上升子序列()。

对两个序列 ,若某个序列 的公共上升子序列,且对于任意的 的公共上升子序列 ,都有 ,那么 称为 的最长公共上升子序列。

例如,给定两个序列 ,其一个最长公共上升子序列为

给定两个长度为 的序列 。请设计一个动态规划算法,求它们的最长公共上升子序列的长度。请描述算法的核心思想,给出算法伪代码并分析其对应的时间复杂度。

  • 分析:对于有序序列 , 其前 个元素组成的子序列 和 前 个元素组成的子序列 的公共子序列具有关系 。对于备选公共子序列,其主要有两种方式得到,一种是以 序列为主序列,在 序列中寻找元素匹配 序列中最后一个元素,并不断扩展 序列长度;另一种是以 序列为主序列,在 序列中寻找元素匹配 序列中最后一个元素,并不断扩展 序列长度。最终将这两种公共子序列长度对比即可获得最长公共子序列。
  • 时间复杂度:最小时间复杂度 ,最大时间复杂度
  • 伪代码:q3

4 叠塔问题

给定 块积木,编号为 。第 块积木的重量为 ( 为整数),硬度为 ,价值为

现要从中选择部分积木垂直摞成一座塔,要求每块积木满足如下条件: 若第 块积木在积木塔中,那么在其之上摆放的所有积木的重量之和不能超过第 块积木的硬度。

试设计算法求出满足上述条件的价值和最大的积木塔,输出摆放方案和最大价值和。请描述算法的核心思想,给出算法伪代码并分析其对应的时间复杂度。

  • 分析:首先应对积木进行排序,使得后规划承重能力强的积木。这里的承重能力指 。若,规划这两块积木时,将放在上面,放在下面,在上还能放 重量的积木;将放在上面,放在下面,在上还能放 重量的积木。而 ,因此此时应该将承重能力更强的2放在下面(后面)。设立二维数组 表示前 块积木,选取总重量为 的积木,搭建的积木塔价值和最大值。对于 ,当选取第 块积木时,其最大值就是 ;当不选取第 块积木时,其最大值就是前 块积木,总重量为 的积木的最大值 。因此,转移方程为
  • 时间复杂度:
  • 伪代码:q4

5 最小划分问题

对一个序列 上的某两个数 ,若 ,则称 为一个不同数对。一个序列 的不同数对数为序列中所有不同数对的个数之和。例如,序列 的不同数对有 四个。

给你一个长度为 的正整数序列 和一个正整数 ,满足序列中的任意一个数 。请你将其划分为 个子段,最小化每个子段最小不同数对数相加的和。你只需要回答这个最小的和。

例如,给定序列为 和参数 ,则答案为 ,对应的一个划分方法为

请使用动态规划求解该问题,描述算法的核心思想,给出算法伪代码并分析其对应的时间复杂度。

  • 分析:设立一维数组 表示从序列开头到第 个元素的不同数对数,设立二维数组 表示从序列开头到第 个元素与第 个元素不同的数对数。对于 ,从序列第 个元素到第 个元素的不同数对数等于 。为降低时间复杂度,可令 。设立二维数组 表示长度为 ,分段数为 时的不同数对数(即所有数对的个数)。对于任意的 ,可以任取一个可分段位置 () ,将前 个元素分为 个子段,其余 个元素作为一个子段,判断这些分段法得出的不同数对数 (即) 的最小值即可。(可选择动态维护此最小值,以降低时间复杂度)
  • 时间复杂度:
  • 伪代码:q5