给定等腰直角数字三角形,请确定从顶至底的某个位置的一条路径,使该路径所经过的数字的总和最大。假设每一步可延直线向下或右斜线向下走。
使用备忘录方法解决数字三角形问题,求解最大数字和、以及其对应的路径。求解将程序粘贴到方框中。
备忘录方法:备忘录方法是动态规划方法的变形。与动态规划算法不同的是,备忘录方法的递归方式是自顶向下的,而动态规划算法则是自底向上的。
代码如下:
#include<stdlib.h>
#include<stdio.h>
#include<time.h>
#include<iostream>
using namespace std;
const int M=5;//数字下三角的行列数
int v[M][M];//数字三角的值
int m[M][M];//从数字三角的(0,0)至(M-1,M-1)的最大和
int lookuptriag(int i,int j)
{
int u1,u2;
if(m[i][j]>0){
return m[i][j];
}
if(i==0&&j==0){
return m[i][j]=v[i][j];
if(i==j)
{
cout<<i<<j<<m[i][j]<<endl;
m[i][j]=lookuptriag(i-1,j-1)+v[i][j];
return m[i][j];
}
else{
if(i>j)
{
if(i!=0&&j==0)
{
m[i][j]=lookuptriag(i-1,j)+v[i][j];
cout<<i<<j<<m[i][j]<<endl;
}
else
{
u1=lookuptriag(i-1,j);
u2=lookuptriag(i,j-1);
m[i][j]=u1>u2?u1+v[i][j]:v[i][j];
return m[i][j];
}
}
}
}
}
void TrackSolution(int i,int j)
{
printf("%d,%d\n",i,j);
while(i!=0||j!=0)
{
if(i==0)
{
j--;
printf("%d,%d\n",i,j);
}
else{
if(j==0)
{
i--;
printf("%d,%d\n",i,j);
}
else{
if(m[i-1][j]>=m[i][j-1])
{
i--;
printf("%d,%d\n",i,j);
}else
{
j--;
printf("%d,%d\n",i,j);
}
}
}
}
}
int main(){
int i,j,start,end,t,count;
printf("随机数生成数字三角形如下:\n");
for(i=0;i<M;i++)
{
for(j=0;j<=1;j++)
{
v[i][j]=rand()%10;
m[i][j]=-1;
printf("%d\t",v[i][j]);
}
printf("\n");
}
count=lookuptriag(M-1,M-1);
printf("备忘录m三角形如下:\n");
for(i=0;i<M;i++)
{
for(j=0;j<=1;j++)
{
printf("%d\t",m[i][j]);
}
printf("\n");
}
printf("TrackSolution(追踪解)如下:\n");
TrackSolution(M-1,M-1);
return 1;
}
代码运行结果如下: