动态规划——数字三角形最大和

题目描述:

求数字三角形从顶层到底层的最大和,路径抉择时只能向下或向右下走。


本题中的数字三角形:

7

3,8

8,1,0

2,7,4,4

4,5,2,6,5


题解:若三角形为等腰三角形或其他形式,先化为上述矩阵的样子方便解答,可用矩阵int [][]matrix={{7},{3,8},{8,1,0},{2,7,4,4},{4,5,2,6,5}}表示。

//***纯递归,找到递归公式便找到了DP_状态转移方程;
	public int triangleSum(int[][] matrix,int m,int n)
	{
		if(m>=matrix.length||n>m)
			return 0;
		
		return  triangleSum(matrix,m+1, n)>triangleSum(matrix,m+1, n+1)?\
                        triangleSum(matrix,m+1, n)+matrix[m][n]:triangleSum(matrix,m+1, n+1)+matrix[m][n];
	}


//***自顶向下记忆化方式
	public  int [][]data=new int[5][5];//这里的matrix为[5][];
	public int triangleSum1(int[][] matrix,int m,int n)
	{
        if(m==matrix.length-1&&n<=m)
        {
        	data[m][n]=matrix[m][n];
        	return data[m][n];
        }
	  //将递归中没有被记录的值记录;
		if(data[m+1][n]==0)
			data[m+1][n]=triangleSum1(matrix,m+1,n);
		if(data[m+1][n+1]==0)
			data[m+1][n+1]=triangleSum1(matrix,m+1,n+1);
      //直接用记录中的值得到本次需要返回的值;
		data[m][n] = data[m+1][n]>data[m+1][n+1]?data[m+1][n]+matrix[m][n]:data[m+1][n+1]+matrix[m][n];
		return data[m][n];
}


//***DP_自底向上递推
	public int [][]path=new int [5][5];//二维数组path用来存放决策的状态;
	public int triangleSum_DP(int[][] matrix,int m,int n)
	{
		int [][]data=new int[5][5];
		for(int i=0;i<5;i++)//递推公式中的边界条件需要额外在矩阵中赋值;
			data[4][i]=matrix[4][i];
		//开始自底向上逐级递推,data为最大和路径矩阵;
		for(int i=4;i>m;i--)
		{
			for(int j=0;j<=i-1;j++)
			{
				if(data[i][j]>data[i][j+1])
				{
					data[i-1][j]=data[i][j]+matrix[i-1][j];
					path[i-1][j]=1;
				}
				else
				{
					data[i-1][j]=data[i][j+1]+matrix[i-1][j];
					path[i-1][j]=2;
				}
			}
		}
		return data[m][n];
	}

//***恢复路径;打印结果为 73875;
//path[5][5] ==[[1, 0, 0, 0, 0], [1, 1, 0, 0, 0], [2, 1, 2, 0, 0], [2, 1, 2, 1, 0], [0, 0, 0, 0, 0]]
	public void pathback(int[][]matrix,int[][]path,int i,int j)
	{
//path[5][5]中第5行的值全部为默认的0,而递归条件是值为1或2则递归,所以数组没有越界。
		System.out.print(""+matrix[i][j]);
		
		if(path[i][j]==1)
			pathback(matrix,path,i+1, j);
		if(path[i][j]==2)
			pathback(matrix,path,i+1, j+1);
	}








你可能感兴趣的:(算法/数据结构)