434
社区成员
发帖
与我相关
我的任务
分享■最优子结构性质当一个问题的最优解包含了其子问题的最优解时,我们说这个问题具有最优子结构。重叠子问题性质在问题的求解过程中,很多子问题的解会被多次使用。
(1. 动态规划法是将待求解问题分解成若干子问题,先求解子问题再结合这些子问题的解得到原问题的解。但动态规划法里的子问题和分治法里的子问题不同,动态规划法中的子问题并不是相互独立的,所以会存在重复计算子问题的情况。
(2. 使用动态规划算法的问题有两个特征:1.有最优子结构性质(子问题的最优解合成原问题的最优解) 2.有重复子问题性质
(3. 动态规划算法采用自底向上的填表法,该法要考虑三个问题:1.表的维数 2.填表的范围 3.按什么顺序填
(另有自上而下的备忘录方法)
(4. 使用动态规划算法时:1.找到最优子结构 2.写出状态表示和状态方程,以及边界条件 3.根据状态方程决定表的维数、范围、填表顺序。 4.填表,先注意边界条件
矩阵联乘问题

/*
思路:这里在考虑的的时候,因为是多个矩阵相乘,求的最小乘法次数,
比如 A1*A2*A3*A4, 那么根据划分的不同,那么其乘法顺序也会不同,继而所求的乘法次数也不一样
划分:((A1*A2)*A3) *A4 等等,那么再求解最小乘法次数的时候,这就涉及到是个
动态的过程
在用 动态划分的思想做的时候,先创建一个二维数组,用来存放不同个数矩阵相乘的
最小乘法次数,然后根据划分 来求得最小的乘法次数
*/
#include<bits/stdc++.h>
using namespace std;
int N;
int p[1000];
int m[1000][1000]; //m[i][j] 即表示:A(i)A(i+1)(i+2)...A(j);
int minimum_num(){
//初始化矩阵,一个矩阵乘法次数为0
for(int i = 1; i <= N; i++)
m[i][i] = 0;
//向二维数组中添加数据,并更新(求最小),
for(int i = N; i >= 1; i--){//这里的i 从 N 先开始,不能从1 先开始,因为一旦从1开始
//那么的话 m[1][N],就在第一次循环便求出,那么m[1][N]在划分
//更新的时候,其中的一些值尚未求出来。如果从N开始,那么最后求得是
//m[1][N],这样就可以用到了前面已经求出的一些值
for(int j = i + 1; j <= N; j++){
//任何一个m[i][j],均可这样先表示出来 即从 i 后面开始划分
m[i][j] = m[i][i] + m[i+1][j] + p[i-1]*p[i]*p[j];
//划分更新
for(int k = i + 1;k < j; k++){//这里 k = i + 1 ,表示的是从i+1后面开始划分,
//因为上方第一次表示出来的时候,就已经是从 i 后面划分了
int temp = m[i][k] + m[k+1][j] + p[i-1] * p[k] * p[j];
if(temp < m[i][j]){
m[i][j] = temp;
}
}
}
}
return m[1][N];
}
int main(){
cin >> N;
for(int i = 0; i < N + 1; i++){
cin >> p[i];
}
int result = minimum_num();
cout << result;
}
或者
#include <bits/stdc++.h>
using namespace std;
const int MAX = 1005;
int p[MAX];
int m[MAX][MAX];
int n;
void matrix()
{
int i,j,r,k;
memset(m,0,sizeof(m));
for(r = 2; r<=n; r++)
{
for(i = 1; i<=n-r+1; i++)
{
j = i+r-1;
m[i][j] = m[i+1][j]+p[i-1]*p[i]*p[j];
for(k = i+1; k<j; k++)
{
int t = m[i][k] +m[k+1][j]+p[i-1]*p[k]*p[j];
if(t<m[i][j])
{
m[i][j] = t;
}
}
}
}
}
int main()
{
cin>>n;
//记录输入的数字,注意个数比n多1
for(int i=0; i<n+1; i++)
cin>>p[i];
matrix();
cout<<m[1][n];
return 0;
}
for(r = 2; r<=n; r++):外层循环,从r=2开始遍历到n,表示矩阵链的长度。
for(i = 1; i<=n-r+1; i++):内层循环,从i=1开始遍历到n-r+1,表示矩阵链的起始位置。
j = i+r-1;:计算矩阵链的结束位置。
m[i][j] = m[i+1][j]+p[i-1]*p[i]*p[j];:根据动态规划的递推关系式,计算m[i][j]的最优值。
for(k = i+1; k<j; k++):再次遍历矩阵链中的每个矩阵,寻找最优值。
int t = m[i][k] +m[k+1][j]+p[i-1]*p[k]*p[j];:计算当前划分位置k时的最优值。
if(t<m[i][j]):如果当前最优值t小于m[i][j],更新m[i][j]为t。
这5个矩阵连乘有多少个可能:11

动态规划问题需要找出递归方程式,设计好所需要填的表格及行列所代表的意义