数字三角形的DFS + DP

算法思路:将每一个位置的三角形数字更新为该数字下面或右下方的最大数字之和,最后得到的数组的值就是三角形路径的最大值

DFS暴搜

沿着一个路径搜索到底,在回溯的路上遇到能走的路径就继续进行搜索,并且已经计算出来的值不用在进行搜索,直接返回,重复搜索的话会导致超时。
数字三角形的DFS + DP_第1张图片

数字三角形的DFS + DP_第2张图片
数字三角形的DFS + DP_第3张图片
大概的搜索如上图所示

代码:

#include
using namespace std;
const int N = 10010;
int f[N][N];
int ans[N][N];
int n;

int dfs(int i, int j){
     
    if(i == n) return f[i][j];//递归结束条件,如果搜索到了底层就直接返回底层的值(边界)
    if(ans[i][j]) return ans[i][j]; //如果被搜索过了就直接返回利用该值即可,不用重复搜索
    return ans[i][j] = max(dfs(i + 1, j), dfs(i + 1, j + 1)) + f[i][j];//每次更新值,去下面和右下方的值进行更新,取最大
}
int main(){
     
    cin >> n;
    for(int i = 0; i < n; i ++ )
        for(int j = 0; j <= i; j ++ )
            scanf("%d", &f[i][j]);
    printf("%d\n", dfs(0, 0));
    return 0;
}

DP

从下往上求最大不存在边界问题

#include
using namespace std;
const int N = 10010;
int f[N][N];
int main()
{
     
	int n;
	cin >> n;
	for (int i = 0; i < n; i++)
		for (int j = 0; j <= i; j++)
			scanf("%d", &f[i][j]);
	for (int i = n - 1; i >= 0; i--)
		for (int j = i; j >= 0; j--)
			f[i][j] = max(f[i + 1][j], f[i + 1][j + 1]) + f[i][j];
	printf("%d\n", f[0][0]);
	return 0;
}

操作过程:

第一次:
1
2 3
4 5 6
7 8 9 10

第二次:
1
2 3
12 14 16

第三次:
1
16 19

第四次:
20

每次从更新一行,改行的数字都更新为该数字和该数字下方或右下方的最大数字之和,每一行都这么作,那么到第一行的那一个数字一定是最大值

你可能感兴趣的:(DP,DFS,c++,算法)