- int intarr[M][N] =
{
{7,0,0,0,0},
{3,8,0,0,0},
{8,1,0,0,0},
{2,7,4,4,0},
{4,5,2,6,5}
};
三角形数租的表示如上。我们很容易想到递归的算法。但是该算法会有许多重复的计算。
int MaxSum_T(int r, int j)
{
if (r == N-1)
return intarr[r][j];
int nSum1 = MaxSum_T(r + 1, j);
int nSum2 = MaxSum_T(r + 1, j + 1);
if (nSum1 > nSum2)
return nSum1 + intarr[r][j];
return nSum2 + intarr[r][j];
}
导致效率不是很高。而且不利于求出路径。
我们采用由低到定的动态规划的算法。
递归额状态方程为D(i,j)=MAX(D(i+1,j),D(i+1,j+1))+intarr[i][j]。
动态规划的代码如下:
#include
using namespace std;
#define M 5
#define N 5
int intarr[M][N] =
{
{7,0,0,0,0},
{3,8,0,0,0},
{8,1,0,0,0},
{2,7,4,4,0},
{4,5,2,6,5}
};
int maxSum[5][5] =
{
{ -1,-1,-1,-1,-1 },
{ -1,-1,-1,-1,-1 },
{ -1,-1,-1,-1,-1 },
{ -1,-1,-1,-1,-1 },
{ -1,-1,-1,-1,-1 },
};
int MaxsumCal(int i, int j)
{
if (i == M)
{
return intarr[i][j];
}
else
{
if (MaxsumCal(i + 1, j) > MaxsumCal(i + 1, j + 1))
{
return MaxsumCal(i + 1, j) + intarr[i][j];
}
else
{
return MaxsumCal(i + 1, j + 1)+ intarr[i][j];
}
}
}
int main()
{
for (int i = 0; i < N; i++)
{
maxSum[N-1][i] = intarr[N-1][i];
}
for (int i = N - 2; i >= 0; i--)
{
for (int j = 0; j <= i; j++)
{
if (maxSum[i + 1][j] > maxSum[i + 1][j + 1])
{
maxSum[i][j] = maxSum[i + 1][j] + intarr[i][j];
}
else
{
maxSum[i][j] = maxSum[i + 1][j + 1] + intarr[i][j];
}
}
}
cout << maxSum[0][0] << endl;
system("pause");
return 0;
}
其实求解路径就是求解maxSum[0][0]逆选择的过程。
我们知道maxSum[0][0]最大,然后求出maxSum[0][0]=MAX(maxSum[1][0],maxSum[1][1])+intarr[0][0],找出大的值就是intarr对应的数组的位置,即最大值路径。
整体代码如下:
#include
#include
using namespace std;
#define M 5
#define N 5
int intarr[M][N] =
{
{7,0,0,0,0},
{3,8,0,0,0},
{8,1,0,0,0},
{2,7,4,4,0},
{4,5,2,6,5}
};
typedef struct Point
{
int x;
int y;
}POINT;
int maxSum[5][5] =
{
{ -1,-1,-1,-1,-1 },
{ -1,-1,-1,-1,-1 },
{ -1,-1,-1,-1,-1 },
{ -1,-1,-1,-1,-1 },
{ -1,-1,-1,-1,-1 },
};
int MaxsumCal(int i, int j)
{
if (i == M)
{
return intarr[i][j];
}
else
{
if (MaxsumCal(i + 1, j) > MaxsumCal(i + 1, j + 1))
{
return MaxsumCal(i + 1, j) + intarr[i][j];
}
else
{
return MaxsumCal(i + 1, j + 1)+ intarr[i][j];
}
}
}
int main()
{
for (int i = 0; i < N; i++)
{
maxSum[N-1][i] = intarr[N-1][i];
}
for (int i = N - 2; i >= 0; i--)
{
for (int j = 0; j <= i; j++)
{
if (maxSum[i + 1][j] > maxSum[i + 1][j + 1])
{
maxSum[i][j] = maxSum[i + 1][j] + intarr[i][j];
}
else
{
maxSum[i][j] = maxSum[i + 1][j + 1] + intarr[i][j];
}
}
}
cout << maxSum[0][0] << endl;
vector<POINT> path;
int i = 0;
int j = 0;
path.push_back({ 0,0 });
while (i < N-1)
{
if (maxSum[i + 1][j] > maxSum[i + 1][j + 1])
{
path.push_back({ i+1,j });
i = i + 1;
j = j;
}
else
{
path.push_back({ i + 1,j+1 });
i = i + 1;
j = j + 1;
}
}
for (auto pp : path)
{
cout << pp.x << " " << pp.y << endl;
}
system("pause");
return 0;
}
执行结果:
动态规划很常用的一种算法。很有用的一种算法。多多掌握啊