动态规划:数字三角形

//
//Number Triangles (出处:IOI '94)
//
//				  如下所示为一个数字三角形:
//
//				  7
//				  3 8
//				  8 1 0
//				  2 7 4 4
//				  4 5 2 6 5
//
//				  请编一个程序计算从顶至底的某处的一条路径,使该路径经过的数字总和最大。
//
//>每一步可沿直线向下或右斜线向下走
//
//>1<行数<=100
//
//>三角形中的数字为整数0..99
//
//【分析】
//
//首先把路线倒过来,即从下往上,直到第一行的数字。
//
//对于一个数字(数字I),到达它的最优路线的最后一步可以是上或左上。不妨假设最后一步是上,那么到达下方数字(数字II)的路径也必须最优。可以 用“剪贴”方法证明这一点:如果到达数字II的路径非最优,那么可以改进路径使数字II的路径更优,这样到达数字I的路径还可以更优,与原先假设数字I路 线已经最优矛盾。所以到达数字II的路径必为最优。
//
//有了最优子结构,我们可以很方便地得出状态转移方程:
//
//f[i,j]=max{f[i+1,j],f[i+1,j+1]}+a[i,j]
//
//初始值:f[n,j]=a[n,j](n为行数)目标值:f[1,1]

#include<stdio.h>

int Tri[5][5]={{7},
               {3,8},
               {8,1,0},
               {2,7,4,4},
               {4,5,2,6,5}};

int dayn(int a[5][5], int m)
{
	int i,j;
	for (i=m-2; i>=0; i--)//3->0
	{
		for (j=0; j<i+1; j++) // 0->i
		{
			printf("%d %d %d  --> ", Tri[i][j],Tri[i+1][j], Tri[i+1][j+1] );
			int t=((Tri[i+1][j]>Tri[i+1][j+1])? Tri[i+1][j] :Tri[i+1][j+1]);
			printf("%dth choose %d  --> ", i, t);
			Tri[i][j] += t ;
			printf("%d %d %d \n", Tri[i][j],Tri[i+1][j], Tri[i+1][j+1] );
			
		}
		printf("\n");
	}
	///
	int nn=Tri[0][0];
	
	return nn;
}
int main()
{
	printf("%d\n",dayn(Tri,5));
	return 0;
}


参考:http://hi.baidu.com/vizdsaauwcbfhnd/item/8193390957092011acdc7047

 

结果:

 

如果是求最小路径:

你可能感兴趣的:(动态规划:数字三角形)