//
//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
结果:
如果是求最小路径:
