假设有如下所示的一个数字金字塔,现在,要求写一个程序来查找从顶点到底部任意处结束的路径,使路径经过的数字的和最大,并输出该路径的最大和。比如以下金字塔的和最大路径的和为7+3+8+7+5=30。
7
3 27
8 1 0
2 7 4 4
4 5 2 6 5
import java.util.Scanner;
/**
* http://acm.hdu.edu.cn/showproblem.php?pid=2084
*/
public class Shuta {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int C = sc.nextInt();
int[][] dp = new int[102][102];
for (int i = 0; i < C; i++) {
int N = sc.nextInt();
for (int j = 1; j <= N; j++) {
for (int k = 1; k <= j; k++) {
dp[j][k] = sc.nextInt();
}
}
for (int j = N; j >= 1 ; j--) {
for (int k = j; k >= 1 ; k--) {
dp[j][k] += Math.max(dp[j+1][k], dp[j+1][k+1]);
}
}
System.out.println(dp[1][1]);
}
}
}
}}
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
int main()
{
vector<vector<int>> b = { {7},{3,2},{8,1,0},{2,7,4,4},{4,5,2,6,5} };
for (int i = b.size() - 2; i >= 0; --i){
for (int j = 0; j < b[i].size(); ++j){
b[i][j] += std::max(b[i + 1][j],b[i + 1][j + 1]);
}
}
cout<<b[0][0]<<endl;
return 0;
}
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
int choice1, choice2, max;
vector<vector<int>> b = { {7},{3,2},{8,1,0},{2,7,4,4},{4,5,2,6,5} };
vector<int>::iterator it = b[b.size() - 1].begin();
print2(b);
for (int r = 0; r < b.size(); ++r) {
for (int c = 0; c < b[r].size(); ++c) {
if (r == 0 && c == 0);
else if (c == 0)
b[r][c] += b[r - 1][c];
else if (c == b[r].size() - 1)
b[r][c] += b[r-1][c-1];
else {
choice1 = b[r-1][c];
choice2 = b[r-1][c-1];
max = choice1 > choice2 ? choice1 : choice2;
b[r][c] += max;
}
}
}
it = max_element(b[b.size()-1].begin(), b[b.size()-1].end());
cout << *it << endl;
return 0;
}
#include <stdio.h>
#define Max(a,b) ((a) > (b) ? (a) : (b))
int main(void)
{
int n = 5, i, k, j;
k = (1 + n) * n / 2;
int a[] = { 7, 3, 2, 8, 1, 0, 2, 7, 4, 4, 4, 5, 2, 6, 5 };
k = k - n;
for (i = k - 1, j = 0; i >= 0; i--)
{
a[i] = a[i] + Max(a[i + n], a[i + n - 1]);
if (++j == n - 1)
{
n--; j = 0;
}
}
printf("%d\n", a[0]);
return 0;
}
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
/************************************************************************/
/*vec存储数值
maxSum当前的最大值
sum走到当前路径的之和
i, j当前处于的位置
size数字的宽度与高度*/
/************************************************************************/
/************************************************************************/
/* 查找路径之和的最大值 */
/************************************************************************/
void getMaxSum(vector<vector<int>>& vec, int *maxSum, int sum, int i, int j, int size)
{
if (0 > i || i >= size || 0 > j || j > i)
return;
sum += vec[i][j];
(*maxSum) = max(*maxSum, sum);
getMaxSum(vec, maxSum, sum, i + 1, j, size);
getMaxSum(vec, maxSum, sum, i + 1, j + 1, size);
}
int main()
{
int size;
int maxSum;
vector<vector<int>> vec;
cin >> size;
for (int i = 1; i <= size; ++i)
{
vector<int> v(i);
for (int j = 0; j < i; ++j)
cin >> v[j];
vec.push_back(v);
}
getMaxSum(vec, &maxSum, 0, 0, 0, size);
cout << maxSum << endl;
return 0;
}
#include <iostream>
#include <cmath>
using namespace std;
const int MAXLAYER = 5; // 金字塔的最大层数
/** @brief
* 计算金字塔中第layer层第pos个元素在数组中的下标
*
* @param layer int 金字塔中第layer层
* @param pos int 金字塔中第layer层第pos个元素
* @return int
*
*/
int Index(int layer, int pos)
{
return layer * (layer - 1) / 2 + pos;
}
/** @brief
* 金字塔自上而下路径中,路径和的最大值
*
* @param pNums int* 存储金字塔中的数字,这里是一维数组,按层次顺序进行存储
* @param layer int 金字塔中的第layer层[1, MAXLAYER]
* @param pos int 金字塔中第layer层的第pos([0, layer-1])个元素
* @return int 最大路径和
*
*/
int MaxPathSum(int *pNums, int layer, int pos)
{
if(MAXLAYER == layer)
{
return pNums[Index(layer, pos)];
}
/**
* 第layer层的第pos个元素,只能向第layer+1层的第pos或第pos+1个元素走
*/
return max(MaxPathSum(pNums, layer + 1, pos + 0), MaxPathSum(pNums, layer + 1, pos + 1))
+ pNums[Index(layer, pos)];
}
int main()
{
// 数组的大小应该为 MAXLAYER * (MAXLAYER + 1) / 2
int nums[] = {7, 3, 2, 8, 1, 0, 2, 7, 4, 4, 4, 5, 2 ,6, 5};
cout << MaxPathSum(nums, 1, 0) << endl;
return 0;
}
#include <cstdio>
#include <algorithm>
int a[500500] = {0};
int dp[500500] = {0};
int main(){
freopen("numtri.in","r",stdin);
int row_num = 0;
scanf("%d", &row_num);
int elem_num = row_num * (row_num + 1) / 2; // 数字金字塔中的元素个数
for(int i = 0;i <elem_num;i++) {
scanf("%d",&a[i]);
}
for(int i=0; i<row_num; i++) {
dp[elem_num-1-i]=a[elem_num-1-i];
}
int n;
for(int i=row_num-2; i>=0; i--){
n = i * (i + 1) / 2;
for(int j=0; j<=i; j++) {
dp[n+j] = a[n+j] + std::max(dp[n+j+i+1], dp[n+j+i+2]);
}
}
freopen("numtri.out","w",stdout);
printf("%d\n",dp[0]);
return 0;
}
#include <cstdio> #include <algorithm> int a[500500] = {0}; int dp[500500] = {0}; int main(){ freopen("numtri.in","r",stdin); int row_num = 0; scanf("%d", &row_num); int elem_num = row_num * (row_num + 1) / 2; // 数字金字塔中的元素个数 for(int i = 0;i <elem_num;i++) { scanf("%d",&a[i]); } for(int i=0; i<row_num; i++) { dp[elem_num-1-i]=a[elem_num-1-i]; } int n; for(int i=row_num-2; i>=0; i--){ n = i * (i + 1) / 2; for(int j=0; j<=i; j++) { dp[n+j] = a[n+j] + std::max(dp[n+j+i+1], dp[n+j+i+2]); } } freopen("numtri.out","w",stdout); printf("%d\n",dp[0]); return 0; }