数字三角形

来源:互联网 发布:xd mac 破解版 编辑:程序博客网 时间:2024/05/17 06:02

数字三角形:

问题描述:

有 n 行组成的数字三角形,找出一条从顶都底路径,使其经过的数字组成的数字之和最大,输出最大值;

思路:

求最大路径有以下几种方法:

  1. 直接枚举所有路径,再比较找出最大路径;
  2. 若设 d(i, j) 为从 i, j 开始的最大路径和,则 d(i, j) = max{ d(i+1, j), d(i+1, j+1)}

对于第二种 DP 情况,定义了状态和状态方程,几种计算方法:

  1. 直接递归(重复计算子问题,复杂度指数级)
  2. 递推存表(避免重复计算子问题,复杂度 n^2)
  3. 递归存表(记忆化搜索)(避免重复计算子问题,复杂度 n^2)

代码:

// 直接枚举搜索// 输出最大路径及其路径#include <iostream>#include <cstdio>using namespace std;const int maxn = 100;int arr[maxn][maxn];int route[maxn];int maxroute[maxn];int n;  // n levelint maxnum;void backtracking(int i, int j){    if(i == n-1)    {        int temp = 0;        route[i] = arr[i][j];        for(int k = 0; k < n; k++)            { printf("%d ", route[k]); temp += route[k]; }        printf("\n");        if(temp > maxnum)        {            maxnum = temp;            for(int k = 0; k < n; k++) maxroute[k] = route[k];        }    }    else    {        route[i] = arr[i][j];        backtracking(i+1, j);        backtracking(i+1, j+1);    }}int main(){    scanf("%d", &n);    for(int i = 0; i < n; i++)        for(int j = 0; j <= i; j++)            scanf("%d", &arr[i][j]);    backtracking(0, 0);    for(int i = 0; i < n; i++) printf("%d ", maxroute[i]);    printf("%d", maxnum);    return 0;}

对 n 层数字三角形,一共有 (1+n)*n/2 个节点;
遍历所有路线有 2^(n-1)条;
这显然是最不理想的状态,因为除了两边的节点,中间的节点都被重复访问了;


// 递归存表#include <iostream>#include <cstdio>using namespace std;const int maxn = 100;int arr[maxn][maxn];int d[maxn][maxn];int n;  // n levelint solve(int i, int j){    if(d[i][j]) return d[i][j];    return d[i][j] = arr[i][j] + ((i == n-1) ? 0 : max(solve(i+1, j), solve(i+1, j+1)));}int main(){    scanf("%d", &n);    for(int i = 0; i < n; i++)        for(int j = 0; j <= i; j++)            scanf("%d", &arr[i][j]);    printf("%d", solve(0, 0));    return 0;}

// 递推存表// 输出最长路径,无具体路径#include <iostream>#include <cstdio>using namespace std;const int maxn = 100;int arr[maxn][maxn];int d[maxn][maxn];int n;  // n levelint main(){    scanf("%d", &n);    for(int i = 0; i < n; i++)        for(int j = 0; j <= i; j++)            scanf("%d", &arr[i][j]);    for(int i = n-1; i >= 0; i--)        for(int j = 0; j <= i; j++)        // 注意优先级            d[i][j] = arr[i][j] + ((i==n-1)?0:max(d[i+1][j], d[i+1][j+1]));    printf("%d", d[0][0]);    return 0;}
0 0
原创粉丝点击