动态规划的几个经典问题

这篇具有很好参考价值的文章主要介绍了动态规划的几个经典问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

矩阵链加括号问题

【问题描述】给定n个矩阵A1, A2 ,…, An, 其中AiAi+1是可乘的计算这n个矩阵的连乘积A1A2…An用加括号的方法表示矩阵连乘的次序。

【输入形式】

输入有2行,第1行输入一个整数n,第2行输入n个矩阵的维度值p0,p1,...,pn

【输出形式】

输出分3部分,第1部分输出二维数组m的值,每个元素占8列,然后输出一个空行,第2部分输出二维数组s的值,也是每个元素占8列,再输出一个空行,第3部分输出加括号的方式

【样例输入】

5

30 35 15 5 10 20
【样例输出】

       0   15750    7875    9375   11875
       0       0    2625    4375    7125
       0       0       0     750    2500
       0       0       0       0    1000
       0       0       0       0       0
 
       0       1       1       3       3
       0       0       2       3       3
       0       0       0       3       3
       0       0       0       0       4
       0       0       0       0       0
 
((A1(A2A3))(A4A5))


【提示】

 文章来源地址https://www.toymoban.com/news/detail-846333.html

输出加括号的格式需要用一个递归函数 

void print(Matrix<int>&S,int i,int j)     //Matrix是一个事先定义好的矩阵类

{   int t;

       if(i==j)

         {  cout<<"A"<<i;

            return;

         }

        cout<<"(";

        

      S.getData(i,j,t);       // 这行代码其实是实现 t=s[i][j]

      print(S,i,t);

      print(S,t+1,j);

      cout<<")";       

}

#include "iostream"
#include "iomanip"
using namespace std;
const int N = 1e3;
int m[N][N],s[N][N], p[N];
int n;
void M(){
	for(int r = 2; r <= n; r ++){
		for(int i = 1; i <= n - r + 1; i ++){
			int j = i + r - 1;
			m[i][j] = m[i][i] + m[i + 1][j] + p[i - 1] * p[i] * p[j ];
			s[i][j]	= i;
			for(int k = i + 1; k < j; k ++){
				if(m[i][k] + m[k + 1][j] + p[i - 1] * p[k] * p[j] < m[i][j])
				{
					m[i][j] = m[i][k] + m[k + 1][j] + p[i - 1] * p[k] * p[j];
					s[i][j] = k;
				} 
				 
			}
			
		}
	}
}
void print(int i,int j)     //Matrix是一个事先定义好的矩阵类

{   int t;
    if(i == j)
     {  cout<<"A"<<i;
        return;
     }
    cout<<"(";
    t = s[i][j];       // 这行代码其实是实现 t=s[i][j] 
    print(i, t);
    print(t+1, j);
    cout<<")";       

}
int main(){
	cin >> n;
	for(int i = 0; i < n + 1; i ++){
		cin>>p[i];
	}
	M();
	 for(int i = 1; i <= n; i++){
    	for(int j = 1; j <= n; j ++){
    		cout<< setw(8) <<m[i][j];
		}
		cout<<endl;
	}
	cout<<endl;
	for(int i = 1; i <= n; i++){
    	for(int j = 1; j <= n; j ++){
    		cout<< setw(8) <<s[i][j];
		}
		cout<<endl;
	}
	cout<<endl;
	print(1, n);
	return 0;
}

 

 

【问题描述】

输入两个序列X和Y,假设序列中都是大写英文字母,且中间没有空格,求出X和Y的最长公共子序列

【输入形式】

输入分2行,分别输入2个序列

【输出形式】

输出分3部分,第1部分输出二维数组C的值,每个元素占3列,然后输出一个空行,第2部分输出二维数组B的值,也是每个元素占3列,再输出一个空行,第3部分输出最长公共子序列,每个字母后加1个空格

把数组B中的方向字符改成用整数表示,0表示 ‘ã’,1表示‘á’,2表示‘ß’


【样例输入】

ABCBDAB
BDCABA

【样例输出】

  0  0  0  1  1  1

  1  1  1  1  2  2

  1  1  2  2  2  2

  1  1  2  2  3  3

  1  2  2  2  3  3

  1  2  2  3  3  4

  1  2  2  3  4  4

 

  1  1  1  0  2  0

  0  2  2  1  0  2

  1  1  0  2  1  1

  0  1  1  1  0  2

  1  0  1  1  1  1

  1  1  1  0  1  0

  0  1  1  1  0  1

 

B C B A

#include "iostream"
#include "iomanip"
#include "vector"
using namespace std;
int B[100][100], C[100][100]; 
vector<char> v;
int main(){
	string a, b;
	cin>>a >>b ;
	for(int i = 0 ; i <= a.length(); i ++){
		for(int j = 0; j <= b.length(); j ++){
			  if(a[i] == b[j]){
				 C[i + 1][j + 1] = C[i][j] + 1;
				 B[i][j] = 0;
			  }
			  else if(C[i + 1][j] <= C[i][j + 1]){
				   C[i + 1][j + 1] = C[i][j + 1];
				   B[i][j] = 1;
			  }
			  else {
				   C[i + 1][j + 1] = C[i + 1][j];
				   B[i][j] = 2;
			  }
		}
	}
	int i = a.length()  - 1, j = b.length() - 1;
	while(i >= 0 && j >= 0){
		if(B[i][j] == 0) v.push_back(a[i]), i --, j --;
		else if(B[i][j] == 1) i --;
		else j --; 
	}
	for(int i = 1; i <= a.length(); i ++){
		for(int j = 1; j <= b.length(); j ++){
			cout<<setw(3)<<C[i][j];
		}
		cout<<endl;
	}
	cout<<endl;
	for(int i = 0; i < a.length(); i ++){
		for(int j = 0; j < b.length(); j ++){
			cout<<setw(3)<<B[i][j];
		}
		cout<<endl;
	}
	cout<<endl;
	while(v.size()){
		cout<<v.back()<<" ";
		v.pop_back();
	}
	return 0;
}

 

 

到了这里,关于动态规划的几个经典问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 探索经典算法:贪心、分治、动态规划等

    贪心算法是一种常见的算法范式,通常在解决最优化问题中使用。 贪心算法是一种在每一步选择中都采取当前状态下最优决策的算法范式。其核心思想是选择每一步的最佳解决方案,以期望达到最终的全局最优解。这种算法特点在于只考虑局部最优解,而不会回溯或重新考虑

    2024年02月05日
    浏览(44)
  • 0-1背包问题:动态规划的经典应用

    背包问题是在给定一组物品和一个背包容量的情况下,如何选择物品放入背包,以使得放入背包的物品总价值最大化。0-1背包问题是背包问题的一个经典变种,其中每个物品要么完全放入背包,要么完全不放入,不能切割物品。在本文中,我们将探讨如何使用动态规划算法解

    2024年02月12日
    浏览(42)
  • 动态规划详细讲解c++|经典例题讲解认识动态规划|0-1背包问题详解

    uu们,你们好!这次的分享是动态规划,其中介绍了动态规划的相关概念和做题模板(三要素),同时为了uu们对动态规划方法有更加形象的认识,特地找了两个经典问题,和大家一起分析。并且呢,为了大家检验自己的学习成果,我专门在常用的oj上为uu们找到了相关题目的

    2024年04月11日
    浏览(60)
  • 经典动态规划问题详解以及其主要应用场景

    ** 动态规划(英语:Dynamic programming,简称 DP),是一种在数学、管理科学、计算机科学、经济学和生物信息学中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。动态规划常常适用于有重叠子问题和最优子结构性质的问题。。 动态规划最核心的思

    2024年02月10日
    浏览(39)
  • Python递归的几个经典案例

    当我们碰到诸如需要求阶乘或斐波那契数列的问题时,使用普通的循环往往比较麻烦,但如果我们使用递归时,会简单许多,起到事半功倍的效果。这篇文章主要和大家分享一些和递归有关的经典案例,结合一些资料谈一下个人的理解,也借此加深自己对递归的理解和掌握一

    2024年02月05日
    浏览(48)
  • 【数据结构与算法】三个经典案例带你了解动态规划

    从表中我们可以看到,最大的公共子串长度为2,一共有两个长度为2的公共子串,分别是第一个字符串的第2个字符到第3个字符和第一个字符串的第3个字符到第4个字符,即 ba 和 ac 根据上面的方法,我们来用代码封装一下求取最大公共子串的函数 function publicStr(s1, s2) { // 创建

    2024年04月09日
    浏览(95)
  • 最长回文子序列问题的原理与实现:动态规划的又一经典应用

    回文是指一个正着读和反着读都一样的字符串,比如 “aba” , “racecar” , “madam” 等。回文有许多有趣的性质和应用,比如在密码学,生物信息学,数据压缩等领域都有涉及。 那么,给定一个字符串,如何找出它的最长回文子序列呢?最长回文子序列是指从原字符串中删

    2023年04月13日
    浏览(49)
  • 【算法深度探索】动态规划之旅(1):挑战OJ题海,解锁15道经典难题,让你成为DP大师!

    📃 博客主页: 小镇敲码人 🚀 欢迎关注:👍点赞 👂🏽留言 😍收藏 🌏 任尔江湖满血骨,我自踏雪寻梅香。 万千浮云遮碧月,独傲天下百坚强。 男儿应有龙腾志,盖世一意转洪荒。 莫使此生无痕度,终归人间一捧黄。🍎🍎🍎 ❤️ 什么?你问我答案,少年你看,下一

    2024年04月11日
    浏览(37)
  • 【算法专题】动态规划之路径问题

    题目链接 - Leetcode -62.不同路径 Leetcode -62.不同路径 题目:一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。 问总共有多少条不同的路径? 示

    2024年01月24日
    浏览(48)
  • 【算法 - 动态规划】找零钱问题Ⅲ

    在前面的动态规划系列文章中,关于如何对递归进行分析的四种基本模型都介绍完了,再来回顾一下: 从左到右模型 : arr[index ...] 从 index 之前的不用考虑, 只考虑后面的该如何选择 。 范围尝试模型 :思考 [L ,R] 两端,即 开头和结尾 处分别该如何取舍。 样本对应模型 :

    2024年04月09日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包