Digital triangles
Describe:
There is a triangle consisting of nonnegative integers, with only one number in the first row, and a number in the lower left and lower right of each number except the most downward line.
Problem:
Start with the number of the first line, each time you can go down to the left or right to the bottom of a grid, until the most downward, the number of passes along the way to add up. How to go to make this and as big as possible.
Analysis:
It's not hard to see that this is a dynamic decision problem: There are two choices each time--lower left or lower right. If we use backtracking method to find all possible routes, we can choose the best route. But as always, backtracking is too inefficient: the complete line of an n-tier digital triangle has a 2^n bar, and the speed of backtracking when n is large is intolerable. Therefore, this discussion uses recursion, recursive memory search method implementation, although there are other methods, but at this time only to learn more similar methods.
the first thought is recursive implementation:
#include "stdio.h"
#define MAXN
int a[maxn][maxn],n;
inline max (int x,int y)
{return
x>y?x:y;
}
Recursive computation implements
int d (int x,int y)
{return
a[x][y]+ (X==n?0:max (X+1,y), D (x+1,y+1)));
int main ()
{
while (~scanf ("%d", &n))
{
int i,j;
for (i=1;i<=n;i++) {
for (j=1;j<=i;j++)
scanf ("%d", &a[i][j]);
printf ("max:%d\n", D (1,1));
}
return 0;
}
While this is true, time efficiency is too low because of repeated computations.
Example: D (3,2) is repeatedly called in the following calculations
The calculation of D (2,1) will call--> D (3,1), D (3,2)
The calculation of D (2,2) will call--> D (3,2), D (3,3)
implementation of recursion:
#include "stdio.h"
#define MAXN
int a[maxn][maxn],n;
inline max (int x,int y)
{return
x>y?x:y;
}
Recursive implementation
int d (int x,int y)
{
int d[n][n],i,j;
for (j=1;j<=n;j++) d[n][j]=a[n][j];
for (i=n-1;i>=1;i--) {for
(j=1;j<=i;j++)
D[i][j]=a[i][j]+max (d[i+1][j],d[i+1][j+1]);
return d[x][y];
}
int main ()
{
while (~scanf ("%d", &n))
{
int i,j;
for (i=1;i<=n;i++) {
for (j=1;j<=i;j++)
scanf ("%d", &a[i][j]);
printf ("max:%d\n", D (1,1));
}
return 0;
}
The realization of the memory search:
#include "stdio.h"
#include "string.h"
#define MAXN
int a[maxn][maxn],n;
int D[MAXN][MAXN]; Memory search using a state memory array
inline max (int x,int y) {return
x>y?x:y;
}
/*
memory words search. The program is divided into two parts. First memset (d,-1,sizeof (d)), initialize D all to-1,
and then write a recursive function:
* *
int distance (int i,int j)
{
if (d) I [j]>=0) return d[i][j];
Return d[i][j]=a[i][j]+ (I==n?0:max (Distance (i+1,j), distance (i+1,j+1)));
/* The
above program is still recursive, but it also saves the results in array d. The title says that each number is non-negative, so
if a D[I][J has been computed, it should be non-negative, so that all D can be initialized to-1 to determine whether
d[i][j]>=0 has been computed.
*/
int main ()
{
while (~scanf ("%d", &n))
{
int i,j;
for (i=1;i<=n;i++) {
for (j=1;j<=i;j++)
scanf ("%d", &a[i][j]);
Memset (d,-1,sizeof (d)); State Memory Array Initialization
printf ("max:%d\n", Distance (1,1));
}
return 0;
}