解题思路:

1、自下而上求解(自上而下求解很难搞,用递归很容易超时)。

2、注意状态转移方程:dp[t][t1]=dp[t][t1]+Max(dp[t+1][t1+1],dp[t][t1]),这个方程后面会详讲。

注意事项:

这道题应该写错了,应该是向下或向右下,例题好像也有问题

一看到这题我一开始就是暴力从上向下递归,后面发现基本都会超时。

可能会有不少人不理解为什么要自下向上查找,很重要的一个原因就是从下向上查找最后只会到一个点上———顶点,也就是最上面的点上。

如果从上往下查找的话就只能用递归了(递推不行,递推不到最优解),这里我还没想到如何优化,估计是用数组记数,减少递归计算次数进行优化,这个大家可以去试试。

自上向下查找用递推是求不出最优解的,比如举个例子


1/*第一层*/

2 3

5 4 3

7 8 9 12/*第四层*/

看这个,自上往下应该先后是1,3,4,9,一共是17。

但实际答案应该是1,3,3,12,一共是19。

dp[t][t1]=dp[t][t1]+Max(dp[t+1][t1+1],dp[t][t1])

从下开始查找最大值,因为始终所有线路会汇聚到一起,所以总的最大可以转化为:

(第一层+第二层+第三层+第四层+...最后一层)=(第一层+第二层+第三层+....+倒数第二层到最后一层的最大值)=(第一层+第二层+第三层+...+倒数第三层到最后一层的最大值)

如此递推下去就能找到最大值



注意事项:

参考代码:

#include <iostream>

#include <cstdio>

#include <cstring>


using namespace std;

const int MAXN=1e6;

int a[110][110],dp[110]; 

int main(){

int T,n; 

cin>>T;

while(T--){

cin>>n;

for(int i=1;i<=n;++i){

for(int j=1;j<=i;++j)

{

cin>>a[i][j];

}

}

for(int i=1;i<=n;++i) dp[i]=a[n][i];

for(int i=n-1;i>=1;--i){

for(int j=1;j<=i;++j){

dp[j]=max(dp[j],dp[j+1])+a[i][j];

}

}

cout<<dp[1]<<endl;

// cout<<ans<<endl;

}

return 0;

}


点赞(0)
 

0.0分

0 人评分

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

评论列表 共有 0 条评论

暂无评论