题目原文
Number Triangles
Consider the number triangle shown below. Write a program that calculates the highest sum of numbers that can be passed on a route that starts at the top and ends somewhere on the base. Each step can go either diagonally down to the left or diagonally down to the right.
7 3 8 8 1 0 2 7 4 4 4 5 2 6 5
In the sample above, the route from 7 to 3 to 8 to 7 to 5 produces the highest sum: 30.
PROGRAM NAME: numtri
INPUT FORMAT
The first line contains R (1 <= R <= 1000), the number of rows. Each subsequent line contains the integers for that particular row of the triangle. All the supplied integers are non-negative and no larger than 100.SAMPLE INPUT (file numtri.in)
5 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5
OUTPUT FORMAT
A single line containing the largest sum using the traversal specified.SAMPLE OUTPUT (file numtri.out)
30
分析
本题的输入数据是类似于下面的一个由数字组成的三角形
7 3 8 8 1 0 2 7 4 4 4 5 2 6 5在三角形中画一条路径,每一个数字只能与下一行的左右两个数字在一条路径上,要求求出所有可能路径上数字和最大的值。
求解的方法非常简单,从三角形底层依次向上累加,每次累加取较大的那个值,最后在三角形顶端的值极为要求的最大值。
例如,对于上述的数字三角形,第一次累加后的结果为:
7 3 8 8 1 0 7 12 10 10 4 5 2 6 5第二次累加后为:
7 3 8 20 13 10 7 12 10 10 4 5 2 6 5继续累加,最后就可得到结果是30。
提交代码
/*
ID:
PROG: numtri
LANG: C++
*/
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
int cal(vector<vector<int> > &tri,int layer)
{
for (int i=0;i!=tri[layer].size();i++)
{
tri[layer][i] += tri[layer+1][i]>tri[layer+1][i+1]?tri[layer+1][i]:tri[layer+1][i+1];
}
if(layer==0)
{
return tri[0][0];
}
else
{
return cal(tri,layer-1);
}
}
int main()
{
ifstream fin("numtri.in");
ofstream fout("numtri.out");
int R;
fin >> R;
vector<vector<int> > tri(R);
for (int i=0;i!=R;i++)
{
tri[i].resize(i+1);
for (int j=0;j!=i+1;j++)
{
fin >> tri[i][j];
}
}
if(R == 1)
fout << tri[0][0] << endl;
else
fout << cal(tri,R-2)<<endl;
return 0;
}
提交结果
TASK: numtri LANG: C++ Compiling... Compile: OK Executing... Test 1: TEST OK [0.003 secs, 3500 KB] Test 2: TEST OK [0.003 secs, 3500 KB] Test 3: TEST OK [0.005 secs, 3500 KB] Test 4: TEST OK [0.008 secs, 3500 KB] Test 5: TEST OK [0.008 secs, 3500 KB] Test 6: TEST OK [0.014 secs, 3500 KB] Test 7: TEST OK [0.057 secs, 3500 KB] Test 8: TEST OK [0.008 secs, 3500 KB] Test 9: TEST OK [0.140 secs, 3500 KB] All tests OK.
官方参考答案
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#define MAXR 1000
int
max(int a, int b)
{
return a > b ? a : b;
}
void
main(void)
{
int best[MAXR], oldbest[MAXR];
int i, j, r, n, m;
FILE *fin, *fout;
fin = fopen("numtri.in", "r");
assert(fin != NULL);
fout = fopen("numtri.out", "w");
assert(fout != NULL);
fscanf(fin, "%d", &r);
for(i=0; i<MAXR; i++)
best[i] = 0;
for(i=1; i<=r; i++) {
memmove(oldbest, best, sizeof oldbest);
for(j=0; j<i; j++) {
fscanf(fin, "%d", &n);
if(j == 0)
best[j] = oldbest[j] + n;
else
best[j] = max(oldbest[j], oldbest[j-1]) + n;
}
}
m = 0;
for(i=0; i<r; i++)
if(best[i] > m)
m = best[i];
fprintf(fout, "%d\n", m);
exit(0);
}