动态规划之走棋盘问题和s1∪s2=s3问题对比

s1∪s2=s3

问题描述

输入三个字符串s1、s2和s3,判断第三个字符串s3是否由前两个字符串s1和s2交错
而成,即不改变s1和s2中各个字符原有的相对顺序,如s1=“aabbcc”,s2=“dbbca”
s3="aadbbcbbcac"时,输出true,s3=“accabdbbca”,输出false
换个表述:s1和s2是s3的子序列,且s1∪s2=s3

解题思路

实现方法

bool isInterleave(string s1, string s2, string s3) {

	int n1 = s1.size();
	int n2 = s2.size();
	int n3 = s3.size();
	if ((n1 + n2) != n3) {
		return false;
	}
	vector<vector<bool> > dp(n1 + 1, vector<bool>(n2 + 1, false));
	// dp[i][j] 以 s1[i] 和 s2[j] 结尾 能否等于 s[i+j-1]
	for (int i = 0; i <= n1; ++i) {
		for (int j = 0; j <= n2; ++j) {
			if (i == 0 && j == 0) {
				dp[i][j] = 1;
			}
			else if (i == 0) {
				dp[i][j] = dp[i][j - 1] && (s2[j - 1] == s3[i + j - 1]);
			}
			else if (j == 0) {
				dp[i][j] = dp[i - 1][j] && (s1[i - 1] == s3[i + j - 1]);
			}
			else {
				dp[i][j] = (dp[i][j - 1] && (s2[j - 1] == s3[i + j - 1])) || (dp[i - 1][j] && (s1[i - 1] == s3[i + j - 1]));
			}
		}
	}
	return dp[n1][n2];
}

走棋盘问题

问题描述

给定m*n的矩阵,每个位置是一个非负整数,从左上角,每次只能朝右和下走,走到右下角,求总和最小的路径

解题思路

实现方法

int getShortRoute(vector<vector<int>>& map) {
	// 矩阵的高
	int heigh = map.size();
	// 矩阵的宽
	int with = map[0].size();

	// 临时矩阵,用于存储0,0到该点的最短距离
	vector<vector<int> > temp(heigh, vector<int>(with, 0));

	// 两层for循环,用于填满二维数组
	for (int i = 0; i < heigh; i++) {
		for (int j = 0; j < with; j++) {

			// 如果是初始点0, 0
			if (i == 0 && j == 0) {
				temp[i][j] = map[i][j];
			}

			// 如果是最左边的一列,那么只能由上向下到达
			else if (i == 0 && j > 0) {
				temp[i][j] = temp[i][j - 1] + map[i][j];
			}

			// 如果是最上一行,那么只能由最左往右到达
			else if (i > 0 && j == 0) {
				temp[i][j] = temp[i - 1][j] + map[i][j];
			}

			// 其他情况,比较是向下到达距离最短,还是从左往右距离最短
			// 将改点设置为最短的距离
			else {
				int goDown = temp[i][j - 1] + map[i][j];
				int goRight = temp[i - 1][j] + map[i][j];
				temp[i][j] = goDown > goRight ? goRight : goDown;
			}
		}
	}
	// 返回终点最终叠加距离
	return temp[heigh - 1][with - 1];
}

方法二:

int minPathSum(vector<vector<int>>& arr) {
	if (arr.size()==0)
	{
		return 0;
	}
	int row = arr.size();
	int clown = arr[0].size();
	vector<vector<int>> dp(row, vector<int>(clown, 0));//储存从左上角到每一个点的最小路径和
	dp[0][0] = arr[0][0];
	int i, j;
	for (i = 1; i < clown; i++)
	{
		dp[0][i] = dp[0][i - 1] + arr[0][i];
	}
	for (i = 1; i < row; i++)
	{
		dp[i][0] = dp[i - 1][0] + arr[i][0];
		for (j = 1; j < clown; j++)
		{
			dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + arr[i][j];
		}
	}
	return dp[row - 1][clown - 1];
}

总结:这里将将两道题的代码放在一起的原因,就是他们的解题方法和代码很相似。

参考博客:https://blog.csdn.net/u010325193/article/details/80345643

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值