常考编程题之动态规划

10 篇文章 0 订阅
6 篇文章 0 订阅

迭代法求斐波那契数列

斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家莱昂纳多·斐波那契(LeonardoFibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、34、……
简单的说从第三位开始,等于前俩数相加。

class Solution
{
	public:
		int fbnq_func(int n)
		{
			int a = 1,b = 1, c = 1;
			for(int i = 3; i <= n; i++)
			{
				c = a+b;
				a = b;
				b = c;
			}
			return c;
		}
		//补一下递归方法
		int fbnq_func1(int n)
		{
			if(n == 0 || n == 1)
				return 1;
			else
				return (fbnq_func1(n-1)+fbnq_func1(n-2));
		}
}

青蛙跳台阶问题

一只青蛙一次可以跳上1级台阶,也可以跳2级台阶,求该青蛙跳上一个n级的台阶 总共有多少种跳法(先后次序不同算不同的结果)
要求:时间复杂度O(n),空间复杂度O(1)
解决思路:
列入不同阶级的跳法总数:1 2 3 5 8 13 21…
与斐波那契数列相似

class Solution
{
	public:
		int jump_func(int n)
		{
			int a = 1,b = 1, c = 1;
			for(int i = 2; i <= n; i++)
			{
				c = a+b;
				a = b;
				b = c;
			}
			return c;
		}
}

求最长子序列问题

class Solution
{
public:
	string x = "";
	string y = "";
	string ans(int i, int j, vector<vector<int>>& b)
	{
		string res = "";
		//递归终止条件
		if (i == 0 || j == 0)
		{
			return res;
		}
		//根据方向,往前递归,然后添加本级字符
		if (b[i][j] == 1)
		{
			res += ans(i - 1, j - 1, b);
			res += x[i - 1];
		}
		else if (b[i][j] == 2)
		{
			res += ans(i-1,j,b);
		}
		else if (b[i][j] == 3)
		{
			res += ans(i,j-1,b);
		}
		return res;
	}
	string func(string s1,string s2)
	{
		//特殊情况
		if (s1.length() == 0 || s2.length() == 0)
		{
			return "-1";
		}
		int len1 = s1.length();
		int len2 = s2.length();
		x = s1;
		y = s2;
		//dp[i][j] 表示第一个字符串到第i位,第二个字符串到第j位为止的最长子序列长度
		vector<vector<int>> dp(len1 + 1, vector<int>(len2 + 1, 0));
		//动态规划数组相加的方向
		vector<vector<int>> b(len1 + 1, vector<int>(len2 + 1, 0));
		//遍历两个字符串每个位置求的最长长度
		for (int i = 1; i <= len1; i++)
		{
			for (int j = 1; j <= len2; j++)
			{
				//遇到两个字符相等
				if (s1[i - 1] == s2[j - 1])
				{
					//考虑由二者都向前一位
					dp[i][j] = dp[i - 1][j - 1] + 1;
					//来自于左上方
					b[i][j] = 1;
				}
				else
				{
					//左边的选择更大,即第一个字符串后退一位
					if (dp[i - 1][j] > dp[i][j - 1])
					{
						dp[i][j] = dp[i - 1][j];
						//来自于左方
						b[i][j] = 2;
					}
					else
					{
						dp[i][j] = dp[i][j - 1];
						//来自于上方
						b[i][j] = 3;
					}
				}
			}
		}
		//获取答案字符串
		string res = ans(len1,len2,b);
		//检查答案是否位空
		return res != "" ? res : "-1";
	}
	
};
//测试
void main()
{
	Solution s1;
	cout << s1.func("adsjakhdkasf","bdkas");
}
//结果 dkas

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值