算法分析与设计实验二(关于动态规划问题)

第一个实验是求矩阵连乘问题

这个m和s是用6*6二维数组

package test1;
 
import java.util.Scanner;
import java.util.*;
public class test1 {
       voidMatrixChain(int p[],int n,int m[][],int s[][])//m[6][6] s[6][6] p[7] n=5
       {
              for(inti=0;i


 

--

(改)n*n变成n+1*n+1二维数组即此题7*7且if(i==0|| j==0) a[i][j]=0;

package test1;
 
import java.util.Scanner;
import java.util.*;
public class test1 {
       voidMatrixChain(int p[],int n,int m[][],int s[][])//m[6][6] s[6][6] p[7] n=5
       {
              for(inti=1;i<=n;i++)m[i][i]=0;
              for(intr=2;r<=n;r++){
                     for(inti=1;i<=n-r+1;i++){
                            intj=i+r-1;
                            m[i][j]=m[i+1][j]+p[i-1]*p[i]*p[j];
                           
                            s[i][j]=i;
 
                            for(intk=i+1;k


c语言版(同学需要,在java的基础上改成c= =)

#include
#include
#include
void MatrixChain(int p[],int n,int **m,int **s)//m[6][6] s[6][6] p[7] n=5
	{
		for(int i=1;i<=n;i++)m[i][i]=0;
		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+1][j]+p[i-1]*p[i]*p[j];
				
				s[i][j]=i;

				for(int k=i+1;k

矩阵连乘问题实际是从底向上进行计算。r的作用是让ij呈↘方向进行。r是由2到6(5次循环),此时的i是1到n-r+1即1-5,1-4,1-3,1-2,1-1;j是i+r-1,即2-6,3-6,4-6,5-6,6-6即第一个循环r=2实际是有m[1][2],m[2][3],m[3][4],m[4][5],m[5][6]。

r=3时是有m[1][3],m[2][4],m[3][5],m[4][6];

r=4时是有m[1][4],m[2][5],m[3][6];

r=5时是有m[1][5],m[2][6];

r=6时是有m[1][6];

然后

m[i][j] { ①0  ,i=j

            ②min{m[i][k]+m[k+1][j]+p[i-1]p[k]p[j]}(i<=k

可以通过代码中定义的自变量为K的循环在i->j中实现比较取最小。

此题还可以通过备忘录的方法进行解答,算法大概思路是,先把m[i][j]循环遍历赋值0

然后写一个方法参数是i,j,比如方法叫做LookupChain(int i,int j)

把上面的m[x]][y]换成LookupChain(x,y);即可。

LookupChain(int i,int j){

if(m[i][j]>0) return m[i][j];

if(i==j)return 0;

int u=LookupChain(i,i)+LookupChain(i+1,j)+p[i-1]*p[i]*p[j];

...类似

}

 

实验2:最长公共子序列

package test1;
 
import java.util.Scanner;
import java.util.*;
public class test1 {
/* c[i][j]{ 0                                 i=j=0;
 *         c[i-1][j-1]+1                      i,j>0;xi=yi;
 *         max{c[i][j-1],c[i-1][j]}           i,j>0;xi!=yi;
 * */
    static void LCSLength(int m,int n,char x[],char y[],int c[][],int b[][]){//c b [m][n]
       int i,j;
       for(i=0;i<=m;i++)c[i][0]=0;
       for(i=0;i<=n;i++)c[0][i]=0;
       for(i=1;i<=m;i++){
           for(j=1;j<=n;j++)
           {
              if(x[i-1]==y[j-1]){
                  c[i][j]=c[i-1][j-1]+1;b[i][j]=1;
              }
              else
                  if(c[i][j-1]<=c[i-1][j]){
                     c[i][j]=c[i-1][j];
                     b[i][j]=2;
                  }
                  else{
                     c[i][j]=c[i][j-1];
                     b[i][j]=3;
                  }
           }
       }
    }
    static void LCS(int i,int j,char x[],int b[][]){
       if(i==0||j==0)return ;
       if(b[i][j]==1){
           LCS(i-1,j-1,x,b);
           System.out.print(x[i-1]);
       }
       else if(b[i][j]==2)LCS(i-1,j,x,b);
       else if(b[i][j]==3)LCS(i,j-1,x,b);
    }
    public static void main(String[] argn){
       char x[]={'A','B','C','B','D','A','B'};
       char y[]={'B','D','C','A','B','A'};
       int c[][]=new int[x.length+1][y.length+1];
       int d[][]=new int[x.length+1][y.length+1];
       LCSLength(x.length,y.length,x,y,c,d);
       System.out.print("      ");
       for(int j=0;j

实际上c[i][o] =0 c[0][j]=0;

然后i,j均到m,n遍历,m是X的长度,n是Y的长度。然后内部通过这种比较方式.

c[i][j]={① 0,i=0,j=0

②c[i-1][j-1]+1,i>0,j>0,x[i]=y[j]

③max{c[i][j-1],c[i-1][j]  }i,j>0,x[i]!=y[j]

以书上的数据x={A,B,C,B,D,A,B};Y={B,D,C,A,B,A}为例得出最长公共子序列为BCBA


 

你可能感兴趣的:(算法分析与设计实验二(关于动态规划问题))