数字三角形

来源:互联网 发布:sql for in 循环语句 编辑:程序博客网 时间:2024/05/21 17:52

https://biancheng.love/problem/493/index

在这样一棵奇怪的树中,每次王木木把一棵弹珠放在最上面的根上,然后让弹珠自由落体,弹珠有可能往左走,也有可能往右走,每次经过一个点,得分加上这个点的价值,那么王木木最多能得多少分呢?

多组数据输入

每组数据第一行为正整数n(0

#include <cstdio> int a[1002][1002]; int n;int sum( int s, int j) {     if(s==n)         return a[s][j];     int s1 = sum(s+1, j);     int s2 = sum(s+1, j+1);     if(s1>s2)         return s1+a[s][j];     return s2+a[s][j];  } int main() {     while(~scanf("%d", &n)){        for( int i = 1; i <= n; i ++ )             for( int j = 1; j <= i; j ++ )                 scanf("%d", &a[i][j]);         printf("%d\n", sum(1, 1));     } }

采用递归的方法。用sum(i,j)表示从第i行的第j个数字开始走到底边最佳路径和
从某点d[i][j]出发,下一步可以走到d[i+1][j]或者d[i+1][j+1],如果选择走d[i+1][j]
sum[i][j]=sum[i+1][j]+d[i][j],如果选择走d[i+1][j+1],sum[i][j]=sum[i+1][j+1]+d[i][j].
选择走那个,只需比较sum[i+1][j]和sum[i+1][j+1]的大小即可。
实现如下:(经OJ评测,TLE)

#include <cstdio> #include<cstring>int a[1002][1002]; int b[1002][1002];int n;int sum( int s, int j) {     if(s==n)         return a[s][j];     if(b[s+1][j]==-1){        int c=sum(s+1,j);    b[s+1][j]=c;}    if(b[s+1][j+1]==-1){        int d=sum(s+1,j+1);     b[s+1][j+1] = d; }     if(b[s+1][j]>b[s+1][j+1])          return b[s+1][j]+a[s][j];      return b[s+1][j+1]+a[s][j];  } int main() {     while(~scanf("%d", &n)){        memset(b,-1,sizeof(b));        for( int i = 1; i <= n; i ++ )              for( int j = 1; j <= i; j ++ )                 scanf("%d", &a[i][j]);         printf("%d\n", sum(1, 1));     }}

2.这样递归计算,大量的子问题需要重复计算。可以采用带备忘的自顶向下法,此方法在递归过程中保存每一个子问题的解,在求解每个子问题时,如果子问题已求解,直接返回保存子问题的值,可大量减少计算时间。

0 0
原创粉丝点击