解题思路:
这是一道较为简单的动态规划题目,明白了其中的思想,解题就很快了。
首先从一个简单的例子入手,我们先假设一个行数为3的三角形。
| 1 | 第一行 | ||
| 2 | 3 | 第二行 | |
| 4 | 5 | 6 | 第三行 |
我们从上往下分析,每加入新的一行,它的路径为它的上方和左上方。若要得出可以获得最大值的最佳路径,可将第 i 行第 j 列的数值加上第 i - 1 行的第 j 列与第 j - 1 列元素中的较大值,逐行递推即可。
但是针对第一列于最后一列的元素而言,一个没有左上方的元素,一个没有上方的元素,所以在实际解题中需要将它们单独提出讨论。
通过上述的思路,我们对这个简单的例子进行分析:
对于第二行的元素而言,仅能加上第一行的元素的值,从而得到:
| 1 | 第一行 | ||
| 2 + 1 = 3 | 3 + 1 = 4 | 第二行 | |
| 4 | 5 | 6 | 第三行 |
对于第三行的元素,第一列与最后一列的元素路径被固定,第二列的元素有了讨论的空间。仅需要比较它上方与左上方元素的值的大小即可,将其中的较大者加到第二列的元素上。
| 1 | 第一行 | ||
| 2 + 1 = 3 | 3 + 1 = 4 | 第二行 | |
| 4 + 3 = 7 | 5 + 4 = 9 | 6 + 4 = 10 | 第三行 |
得到从上往下相加的最大值为 10。
接下来,我们对这个思路进行代码实现。
for(int i = 0; i < n; i ++){
for(int j = 0; j < i + 1; j ++){
scanf("%d", &An[i][j]);
if(i >= 1){
if(j == 0) // 当元素为第一列时的情况
An[i][j] += An[i -1][j];
else if(j == i) // 当元素处于最后一列的情况
An[i][j] += An[i - 1][j - 1];
else{ // 正常情况下可以使用一个三目运算符得到上方与左上方元素的较大值
int max1 = An[i - 1][j - 1]>An[i - 1][j] ? An[i - 1][j - 1] : An[i - 1][j];
An[i][j] += max1;
}
}
}
} 继续运用三目运算符与for循环的结合,得到最后一行元素中的最大值即为答案。
int max = An[n - 1][0]; for(int j = 0; j < n - 1; j ++) max = max > An[n - 1][j + 1] ? max : An[n - 1][j + 1];
这个过程也可以与上方的情况讨论相结合,为了理解与修改方便,还是将其分开。
最后按照题目要求,在这个for循环的外围再加上一层循环来实现多次分批地输入,便完美完成。
最后附上完整的代码。
参考代码:
#include int main() {
int times;
scanf("%d", ×);
for(int t = 0; t < times; t ++){
int n;
scanf("%d", &n);
int An[n][n];
// ----------------------------------------------
for(int i = 0; i < n; i ++){
for(int j = 0; j < i + 1; j ++){
scanf("%d", &An[i][j]);
if(i >= 1){
if(j == 0)
An[i][j] += An[i -1][j];
else if(j == i){
An[i][j] += An[i - 1][j - 1];
}
else{
int max1 = An[i - 1][j - 1]>An[i - 1][j] ? An[i - 1][j - 1] : An[i - 1][j];
An[i][j] += max1;
}
}
}
}
// ----------------------------------------------
int max = An[n - 1][0];
for(int j = 0; j < n - 1; j ++)
max = max > An[n - 1][j + 1] ? max : An[n - 1][j + 1];
printf("%d\n", max);
}
return 0;
} 若有改进,欢迎与我讨论٩(˃̶͈̀௰˂̶͈́)و。
0.0分
6 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
@纯鹿人 } } int sum=0; for(int j=0;j<=n;j++){ sum=max(sum,d[n-1][j]); } printf("%d",sum); } } return 0; }同样的思路为什么我的不对呀[哭] #include<stdio.h> int max(int a, int b){ if(a>b) return a; else return b; } int main() { int x,n; scanf("%d%d",&x,&n); for(int i=0;i<x;i++){ int a[n][n]; for(int i=0;i<n;i++){ for(int j=0;j<=i;j++){ scanf("%d",&a[i][j]); } } if(n==1) printf("%d",a[0][0]); else{ int d[n][n]; d[0][0]=a[0][0]; d[1][0]=a[0][0]+a[1][0]; d[1][1]=a[0][0]+a[1][1]; for(int i=2;i<n;i++){ for(int j=0;j<=i;j++){ if(j==0) d[i][j]=d[i-1][j]+a[i][j]; else if(j==i) d[i][j]=d[i-1][j-1]+a[i][j]; else d[i][j]=max(d[i-1][j]+a[i][j],d[i-1][j-1]+a[i][j]);