首页 > 试题广场 >

假设有如下所示的一个数字金字塔,现在,要求写一个程序来查找从

[问答题]
假设有如下所示的一个数字金字塔,现在,要求写一个程序来查找从顶点到底部任意处结束的路径,使路径经过的数字的和最大,并输出该路径的最大和。比如以下金字塔的和最大路径的和为7+3+8+7+5=30。

7
3 2
8 1 0
2 7 4 4
4 5 2 6 5
推荐
#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;
}

编辑于 2014-12-03 23:16:45 回复(1)
#include<stdio.h>
#
define MAX(a,b) ((a)>(b)?(a):(b))
int main(){
int dp[99][99],a[99][99],i,j;
for(i=0;i<=4;i++){
    for(j=0;j<=i;j++)
    scanf("%d",&a[i][j]);
}
for(j=0;j<5;j++){
    dp[4][j]=a[4][j]; //给最后一行的dp数组赋值
}    
for(i=3;i>=0;i--){
    for(j=0;j<=i;j++){
        dp[i][j]=a[i][j]+MAX(dp[i+1][j],dp[i+1][j+1]);
    }
}
printf("最长路径的长度是:%d\n",dp[0][0]);
}
发表于 2020-03-13 22:29:19 回复(0)
 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]);
        }

    }
}
发表于 2018-09-01 15:16:41 回复(0)
#include <iostream>
#include <vector>
using namespace std;
vector<double> vv;
double pyramid[10000][10000];
double mm=-10000;
void findMax(vector<double> &v,int l){
    if(l==v.size()){
        int sum=0;
        for(int i=0;i<v.size();i++) sum+=v[i];
        if(sum>mm){
            vv.clear();
            for(double s:v) vv.push_back(s);
            mm=sum;   cout<<"Max: "<<mm<<endl;
  }
    }
    else{
        for(int j=0;j<=l;j++){
            v[l]=pyramid[l][j];
            findMax(v,l+1);
            v[l]=0;
        }
    }
}

int main(){
    int level;
    cin>>level;
    for(int i=0;i<level;i++){
        for(int j=0;j<=i;j++) cin>>pyramid[i][j];
    }
    
    vector<double> v(level);
    findMax(v,0);
    for(int i=0;i<4;i++) cout<<vv[i]<<"+";
    cout<<vv[4]<<endl;
    
    return 0;
        
}
发表于 2019-03-02 22:48:56 回复(0)
#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;
}

编辑于 2017-12-14 15:00:29 回复(0)
转移方程:a[i][j]=max(a[i+1][j],a[i+1][j+1])

发表于 2017-11-30 21:16:36 回复(0)
def longest_slide_down(pyramid)
    pyramid.reverse.reduce([0]*(pyramid.size + 1)) { |result, x|
        (0...result.size-1).reduce([]) do |acc, i| 
            acc + [[result[i], result[i+1]].max + x[i]]
        end
    }[0]
end

发表于 2017-10-15 22:36:36 回复(0)
#include<iostream>
using namespace std;
int a[200];
int get_sum(int line,int n,int start){
    int pos=(line-1)*line/2+start;
    if(line==n){
        if(start==line-1)
            return a[pos];
        else
            return a[pos]>a[pos+1]?a[pos]:a[pos+1];
    }//if
    else{
        if(start==line)
            return a[pos]+get_sum(line+1,n,start);
        else{
            int sum1=a[pos]+get_sum(line+1,n,start);
            int sum2=a[pos+1]+get_sum(line+1,n,start+1);
            return sum1>sum2?sum1:sum2;
        }
    }//else
}//get_sum
int main(){
    int n=0;
    int i=0;
    int result=0;
    while(cin>>n){
        for(i=0;i<(n+1)*n/2;++i)
            cin>>a[i];
        result=get_sum(1,n,0);
        cout<<result<<endl;
    }//while
    return 0;
}//main

发表于 2017-07-08 13:47:17 回复(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;
}

发表于 2016-09-29 14:04:12 回复(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;
}
编辑于 2016-01-11 21:00:22 回复(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;
}

编辑于 2015-09-10 21:41:33 回复(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;
}

编辑于 2015-09-09 15:36:11 回复(0)
xxj头像 xxj
#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;
}
发表于 2014-12-11 11:34:12 回复(0)