动态规划【数据结构与算法笔记3】

注:2019-09-13,MOOC北大程序设计与算法第六周,动态规划2
不建议新手看我的c++ 版本,怕误导人…

1最长上升子序列问题【回顾复习】

1:maxlen[n],状态数组,最终会记录最长上升子序列的数值

int main() {
	const SIZE 101;
	int len1[SIZE];
	int n;
	int maxlen[n];
	cin >> n;
	cout << "你所选择的数组长度是:" << n << "请输入 -" << n << "个数字放入数组" << endl;
	
	for (int i = 0; i < n; i++) {
		cin >> len1[i];
		maxlen[i] = 1;
	}
	cout << "输入完毕,开始计算 .\n";

	for (int i = 1; i < n; i++)
		for (int k = 0; k < i, k++)
			if len1[k] < len1[i]
				maxlen[i] = max(maxlen[i], maxlen[k]) + 1;

	return 0;


}

一年半之前刚学程序语言碰上递归,到4399玩了半小时汉诺塔才通关。到现在这么长时间过去了。递归主要是表述想法的时候比较简便,真正理解后其实也很好懂,但是实际应用还是递推。

2,最长公共子序列

给定两个字符串,找到共有的两个最长排列字符
例如 “abcdgfr”和 “acklrdg” 就是 “acdg” 输出值为4

没看课程,自己先想了一会,这个状态构造没想出来。。。有点菜
主要碰到遍历问题,却没想到用二维数组来解决
解决方案:
1,状态构建: 二维数组(方阵)total,长度为最大的字符串长度
2,状态转移:田字格,右下角与其他三格之间的转换,注意转换只能是相邻之间,我之前想的用一位数组就是遇到了这个问题,无法进行转换

python:
import numpy as np
strx = ['abcdgrf', 'acklrdg']
len1 = len(strx[0])
len2 = len(strx[1])
matrix = np.zeros(len1+1, len2+1])
matrix = matrix.astype(np.int8).tolist()
for i in range(1, len1+1):
    for k in range(1, len2+1):
        if strx[0][i-1] == strx[1][k-1]:
            matrix[i][k] = matrix[i-1][k-1] + 1
        else:
            matrix[i][k] = max(matrix[i][k-1], matrix[i-1][k]
print(matrix[len1][len2])
c++

本想用中文字符串,但似乎c++ 遍历中文字符串不太OK,毕竟还是初学,暂时用字母吧:

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main() {
	string str1 = "abcfgry";

	string str2 = "abfgcyrlj";

	const int len1 = str1.size();//得到最大字符串长度
	const int len2 = str2.size();
//	cout << len1 << endl;
	int matrix[len1 + 1][len2 + 1];

	// 初始化其中一个字符串长度为0时候的矩阵元素为0
	int i, j;
	for (i = 0; i <= len1; i++)
		matrix[i][0] = 0;
	for (j = 0; j <= len2; j++)
		matrix[0][j] = 0;
	for (int i = 1; i <= len1; i++)
		for (int j = 1; j <= len2; j++)
			if (str1[i - 1] == str2[j - 1])
				matrix[i][j] = matrix[i - 1][j - 1]+1;
			else
				matrix[i][j] = max(matrix[i][j - 1], matrix[i - 1][j]);

	cout << matrix[len1][len2];
	return 0;

}

总结
动态规划问题核心就是 1 问题拆解 2,状态构建 3,状态转移

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值