算法复习之动态规划(4)

问题:回文子序列个数

题目描述

        求字符串中回文子序列的个数。(如CDC的回文子序列包括C,D,C,CC,CDC,共5个,位置不同的相同序列需要重复计数)

分析

定义状态

        思考的方式几乎与求解最长回文子序列相同,由于最后需要统计个数,所以我们需要将状态定义为:f(i,j)表示位置ii,j之间回文子序列的个数

状态转移

        我们同样需要考虑在位置i,j之间的回文子序列的个数是由哪几种情况转化过来的

        (1)在位置i+1,j之间的回文子序列个数,添加了第i位

        (2)在位置i,j-1之间的回文子序列个数,添加了第j位

        但这两种存在着叠加了两次的公共部分,即为位置i+1,j-1之间的回文子序列个数;不过此部分在第i位与第j位字符相同的情况下时,还是需要再添加上1,因为原有的回文子序列左右两端同时加上两个一样的字符还会构成回文子序列,并且其本身也会构成一个回文子序列。所以总结起来,其状态转移方程如下:

f(i,j)=f(i+1,j)+f(i,j-1)-\delta (s_i\neq s_j)f(i+1,j-1)+\delta (s_i=s_j)

 边界条件

        同最长回文子序列,起始状态依然是任意位置都为一个回文子序列,即f(i,i)=1,所求值为f(0,n-1)

求解方法

递归

int CPC(vector<char>& s, int i, int j) {
	if (i == j) {
		return 1;
	}
	if (i > j) {
		return 0;
	}
	if (s[i] == s[j]) {
		return CPC(s, i + 1, j) + CPC(s, i, j - 1) + 1;
	}
	return CPC(s, i + 1, j) + CPC(s, i, j - 1) - CPC(s, i + 1, j - 1);
}

        普通的递归求解办法,但是由于递归深度的限制此思路仅仅要求了解即可。 

动态规划(打表法)

int CPC(vector<char>& s, int n) {
	vector<vector<long>> res(n, vector<long>(n, 0));
	for (int i = 0; i < n; i++) {
		res[i][i] = 1;
	}
	for (int i = 1; i < n; i++) {
		long count = 0;
		for (int j = i - 1; j >= 0; j--) {
			if (s[j] == s[i]) {
				count = (res[j + 1][i] + res[j][i - 1] + 1);
			}
			else {
				count = (res[j + 1][i] + res[j][i - 1] - res[j + 1][i - 1]);
			}
			res[j][i] = count;
		}
	}
	return res[0][n - 1];
}

         使用记忆化搜索的动态规划方法可以减少递归查找的迭代深度,避免了超时错误的出现。 

时间复杂度

        根据搜索过程可以判断出时间复杂度为O(n^2)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Python算法复习可以从以下几个方面入手: 1.数据结构:Python中常用的数据结构有列表、元组、字典、集合等,需要掌握它们的基本操作,如增删改查等。 2.排序算法:常见的排序算法有冒泡排序、选择排序、插入排序、快速排序、归并排序等,需要了解它们的原理和实现方法。 3.查找算法:常见的查找算法有顺序查找、二分查找、哈希查找等,需要了解它们的原理和实现方法。 4.递归算法:递归是一种常见的算法思想,需要了解递归的原理和实现方法,并能够熟练地运用递归解决问题。 5.动态规划算法动态规划是一种常见的算法思想,需要了解动态规划的原理和实现方法,并能够熟练地运用动态规划解决问题。 6.贪心算法:贪心算法是一种常见的算法思想,需要了解贪心算法的原理和实现方法,并能够熟练地运用贪心算法解决问题。 7.图论算法:图论是一种常见的算法思想,需要了解图论的基本概念和算法,如最短路径算法、最小生成树算法等。 8.字符串算法:字符串算法是一种常见的算法思想,需要了解字符串匹配算法、编辑距离算法等。 以下是一个例子,演示如何使用Python实现冒泡排序算法: ```python def bubble_sort(arr): n = len(arr) for i in range(n): for j in range(0, n-i-1): if arr[j] > arr[j+1]: arr[j], arr[j+1] = arr[j+1], arr[j] arr = [64, 34, 25, 12, 22, 11, 90] bubble_sort(arr) print("排序后的数组:") for i in range(len(arr)): print("%d" % arr[i]) ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小糖豆豆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值