求数字三角形的最大值,并且求出最大值走的路径

  1. 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;

}
执行结果:
在这里插入图片描述
动态规划很常用的一种算法。很有用的一种算法。多多掌握啊

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值