动态规划概念:动态规划与分治法类似,其基本思想是将求解问题分解成若干子问题,先求解子问题,再结合这些子问题的解得到原问题的解。与分治法不同的是,适合用动态规划求解的问题经分解得到的子问题往往是不相互独立的。
矩阵连乘
问题描述:给定n个矩阵{A1,A2,…,An},其中Ai与Ai+1是可乘的(i=1,2,…,n-1)。考察这n个矩阵的连乘积A1A2…An。求n个矩阵求其最优解。
//计算最优值
void Matrixchain(int *p,int n,int **m,int **s){ //m[i][j]表示从i到j的最优计算量,s[i][j]表示从i到j的最优分割点
for(int i=1;i<=n;i++){ //边界条件,当只有一个矩阵时,最优计算量为0
m[i][i]=0;
}
for(int r=2;i<=n;r++){ //r表示链长,当链长为n的时候,即最终结果从i到j的最优分割点和最优计算量
for(int 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]; //计算初始从i到j当分隔点为i时的初始最优解
s[i][j]=i;
for(int k=i+1;k<j;k++){ //寻求m[i][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;
s[i][j]=k;
}
}
}
}
}
//构造最优解
void Traceback(int i,int j,int **s){
if(i==j) //当i等于j的时候为边界条件,此时只有一个矩阵是最优解
return;
Traceback(i,s[i][j],s);
Traceback(s[i][j+1],j,s);
printf("Multiply A %d,%d"i,s[i][j]);
printf("And A %d,%d"s[i][j]+1,j);
}
凸三角形最优三角剖分
算法思想:用递推的思想求出,最优三角形剖分
主体思想:初始将凸多边形中含三个顶点时的解进行遍历求出顶点为三个时的优解,然后再将顶点数增加依次求出凸多边形中含4个顶点的最优解,5个顶点的最优解直到求出含全部顶点的最优解。
具体实现:将t【i】【j】看作由顶点i-1到顶点j的最优计算量
其中t【i】【j】=t【i,k】+t【k+1】【j】+w(i-1,k,j)表示将顶点以k为(中间点)分割点的最优计算量
递归关系:边界条件为 i=j 当i-j时,只含二个顶点权值为0;
i<j时,t【i】【j】=min{ t【i,k】+t【k+1】【j】+w(i-1,k,j)} 其中w(i,k,j)
表示以k为中间点(分割点)|vivk|+|vjvk|+|vkvi|的距离之和。
void MinSjpf(int n,int **t,int **s){
for(i=1;i<=n;i++){ //边界条件,当只有二个顶点时,无法构成三角形,周长为0,故初始化为0
t[i][i]=0; //注意t[1][1]表示从第0个顶点到第1个顶点二个顶点,t[i][j]表示从第i-1个顶点到第j个顶点
}
for(int r=2;r<=n;r++){ //r=2时表示三个顶点
for(int i=1;i<n-r+1;i++){
j=i+r-1;
t[i][j]=t[i+1][j]+w(i-1,i,j);
s[i][j]=i;
for(int k=i+1;k<j;k++){
int u=t[i,k]+t[k,j]+w(i-1,k,j);
if(u<t[i][j]){
t[i][j]=u;
s[i][j]=k;
}
}
}
}
}