section 1.5 numtri

5 篇文章 0 订阅
4 篇文章 0 订阅

-首先想到的这个方法太笨了
-还是需要递归算法

/*
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; 
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值