-首先想到的这个方法太笨了
-还是需要递归算法
/*
ID: penglin3
PROG: numtri
LANG: C++11
*/
#include <iostream>
#include <fstream>
#include <vector>
#include <math.h>
using namespace std;//fstream 需要std合法范围
#define max(a,b) (a > b ? a : b)
//一个为vector换算二维坐标的函数,y是行数,x表示行中第几个数,都是从0开始算,和数学坐标对应
long coordinate(const int& y, const int& x);
//因为最高有1000行,数字已经不太行了,用一个bool型数组来模拟加法运算,数组的下标大小表示位数的高地
void add1(bool *num, const int& n);
//一个遍历路径的函数,路径用二进制数表示(如五行的时候四次方向选择1001),0表示左,1表示右
//最后一行直接选择比较大的那个数,减少些许遍历
long maxsum(const int& n, const vector<int>& numtri);
int main() {
ifstream fin("numtri.in");
ofstream fout("numtri.out");
//读入数据
int n,basket;
fin >> n;
vector<int> numtri{};
for (int i = 0; i != n*(n + 1) / 2; ++i)
{
fin >> basket;
numtri.push_back(basket);
}
//输出结果
fout << maxsum(n,numtri) << endl;
fin.close();
fout.close();
return 0;
}
//一个为vector换算二维坐标的函数,y是行数,x表示行中第几个数,都是从0开始算,和数学坐标对应
long coordinate(const int& y, const int& x){
return (long)y*(y + 1) / 2 + x;
}
//因为最高有1000行,数字已经不太行了,用一个bool型数组来模拟加法运算,数组的下标大小表示位数的高地
void add1(bool *bit, const int& n)
{
int i = 0;
while (i < n-1 && bit[i])
{
bit[i] = false;
++i;
}
bit[i] = !bit[i];//如果i= n - 1,传入的数组元素个数为n。
return;
}
//一个遍历路径的函数,路径用二进制数表示(如五行的时候四次方向选择1001),0表示左,1表示右
//最后一行直接选择比较大的那个数,减少些许遍历
long maxsum(const int& n, const vector<int>& numtri) {
int x, maxsum = numtri[0], sum;
bool bit[999] = {};//1000行,只需要做999次换行选择。数组初始值从0开始,所以
while(!bit[n-2]){
x = 0; sum = numtri[0];
for (int j = 0; j < n - 2; ++j) {//j表示变换次数
x += (bit[j] ? 1 : 0 );
sum += numtri[coordinate(j + 1, x)];
}
sum+=max(numtri[coordinate(n - 1 , x)],numtri[coordinate(n - 1, x + 1)]);
maxsum = max(maxsum, sum);
add1(bit, n-1);
}
return maxsum;
}
-写了一下,发现是需要迭代
-从最后一层开始迭代
/*
ID: penglin3
PROG: numtri
LANG: C++11
*/
#include <iostream>
#include <fstream>
#include <vector>
#include <math.h>
using namespace std;//fstream 需要std合法范围
#define max(a,b) (a > b ? a : b)
//一个为vector换算二维坐标的函数,y是行数,x表示行中第几个数,都是从0开始算,和数学坐标对应
long coordinate( const int& x, const int& y);
//逐级递归取最大值函数
void maxsum(vector<long> &numtri, const int& n);
int main() {
ifstream fin("numtri.in");
ofstream fout("numtri.out");
//读入数据
int n, basket;
fin >> n;
vector<long> numtri{};
for (int i = 0; i != n*(n + 1) / 2; ++i)
{
fin >> basket;
numtri.push_back(basket);
}
maxsum(numtri, n);//迭代处理
fout << numtri[0] << endl;
fin.close();
fout.close();
return 0;
}
//一个为vector换算二维坐标的函数,y是行数,x表示行中第几个数
//x从0开始算,y从1开始算,和数学坐标对应
long coordinate(const int& x, const int& y){
return (long) x + y*(y - 1) / 2;
}
//从最后一层开始迭代
void maxsum(vector<long> &numtri, const int& n) {
if (n > 1) {
for (int i = 0; i != n - 1; ++i) {
numtri[coordinate(i, n - 1)]+=max(numtri[coordinate(i, n)], numtri[coordinate(i + 1, n)]);
}
maxsum(numtri, n - 1);
}
return;
}