c++ 如何求最大乘积的和?

yyyllmsg  于 2023-11-19  发布在  其他
关注(0)|答案(1)|浏览(108)

当给定n个整数时,你可以将两个数字相乘,也可以让它们保持原样。我写了一个算法来求所有值相加的最大值。
例如,输入是:
9(数组长度)-1 -8 2 1 3 6 -5 0 1
输出必须为62:
62=-8x-5+0x-1+6x3+2+1+1
如果数组是7 4 1 2 5 3 1 9 0,答案应该是91。如果数组是-13 7 -12 13 -8 4 12 7 15 6 -2 10 9 15 4 1 -15,答案应该是838。
我的代码是这样的:

#include <iostream>
#include "sop.h"
using namespace std;

sop::sop() {
    this->num = 0;
    this->array = NULL;
}

sop::sop(int* a, int n) {
    this->num = n;
    this->array = new int[n];
    for (int i = 0; i < n; i++) this->array[i] = a[i];
}

sop::~sop() {
    if (this->array) {
        delete[] this->array;
    }
    this->num = 0;
    this->array = NULL;
}

void sop::printArray(void) {
    if (!this->num)  return;
    for (int i = 0; i < num; i++) cout << array[i] << "  ";
    cout << endl;
}

int myMax(int a, int b) {
    return (a > b) ? a : b;
}

int sop::maxSOP() {
    if (num == 0) return 0;
    if (num == 1) return array[0];

    int maxSum = array[0]; // Initialize maxSum to the first element
    int currentMax = array[0]; // Initialize currentMax to the first element

    for (int i = 1; i < num; i++) {
        int temp = currentMax; // Store the previous currentMax

        // Calculate the current maximum product including the current element
        currentMax = myMax(array[i], myMax(currentMax * array[i], temp * array[i]));

        // Update maxSum with the maximum of maxSum and currentMax
        maxSum = myMax(maxSum, currentMax);
    }

    return maxSum;
}

字符串
maxSOPmyMax是我做的。
在这段代码中,结果是288,而不是62。我不知道为什么。你能修复这段代码吗?我会给你看其他文件,可以帮助你修复这段代码。
otherfile.cpp

#include <iostream>
#include <fstream>
#include "sop.h"
using namespace std;

int main(int argc, char* argv[]) {
    int i = 0;
    int num = 0;
    int* array = NULL;
    ifstream fin;
    sop* _sop = NULL;

    if (argc > 1) {
        fin.open(argv[1]);
        if (!fin.is_open()) {
            cerr << "File " << argv[1] << " does not exist!" << endl;
            exit(0);
        }
        fin >> num;
        array = new int[num];
        for (i = 0;i < num;i++)        fin >> array[i];
        fin.close();
    }
    else {
        cin >> num;
        array = new int[num];
        for (i = 0;i < num;i++)        cin >> array[i];
    }

    _sop = new sop(array, num);
    cout << "Input array: ";
    _sop->printArray();
    cout << "Maximum sum of products = " << _sop->maxSOP() << endl;
    delete _sop;
    if (array)       delete[] array;
    array = NULL;
    return 0;
}


otherheader.h

#include <iostream>
#include <fstream>
#include "sop.h"
using namespace std;

int main(int argc, char* argv[]) {
    int i = 0;
    int num = 0;
    int* array = NULL;
    ifstream fin;
    sop* _sop = NULL;

    if (argc > 1) {
        fin.open(argv[1]);
        if (!fin.is_open()) {
            cerr << "File " << argv[1] << " does not exist!" << endl;
            exit(0);
        }
        fin >> num;
        array = new int[num];
        for (i = 0;i < num;i++)        fin >> array[i];
        fin.close();
    }
    else {
        cin >> num;
        array = new int[num];
        for (i = 0;i < num;i++)        cin >> array[i];
    }

    _sop = new sop(array, num);
    cout << "Input array: ";
    _sop->printArray();
    cout << "Maximum sum of products = " << _sop->maxSOP() << endl;
    delete _sop;
    if (array)       delete[] array;
    array = NULL;
    return 0;
}

2skhul33

2skhul331#

基本上,如果你能有效地将数字配对在一起,你就能得到最大的和。我建议遵循以下规则:
1.数字<= 0应成对出现。
对于n1 <= 0n2 <= 0n1 * n2 >= n1 + n2
n1 <= 0n2 > 0配对相反:n1 * n2 < n1 + n2不是我们想要的配对。

  1. 1的永远不应该配对。
    同上:如果我们将n与1配对,则结果乘积将始终小于n+1
    1.大于1的数字应该成对出现。
    无论n1 > 1n2 > 1是什么,n1 * n2 >= n1 + n2(只有当n1 = n2 = 2时,两边相等;在其他任何情况下,这都是一个严格的不等式)。
    1.当你有两个以上的数字可以配对时(如上面3条规则所述),总是先选择绝对值较大的数字。
    3个整数1 < n1 <= n2 <= n3的示例:
    n2 * n3 + n1 >= n1 * n3 + n2 >= n1 * n1 + n3 >= n1 + n2 + n3的一个。
    对于4个整数1 < n1 <= n2 <= n3 <= n4也有类似的情况:可以构建的最大组合是n1 * n2 + n3 * n4
    这基本上使我们走上正轨;我们必须:
    1.对数字进行排序(根据规则4)
    1.在每一步,我们首先处理成对的项(即,将迭代器增加2),然后,如果该段具有奇数个元素,则将最小(绝对值)的剩余项添加到和中。
    该算法看起来有点不对称,因为1应该在向量的中间,我们将在负数循环之后处理它们(而不是从numbers.begin()重新开始)。
#include <algorithm>
#include <vector>
int main(int argc, char* argv[])
{
    //std::vector<int> numbers{ -1, -8, 2, 1, 3, 6, -5, 0, 1 };
    //std::vector<int> numbers{ 7, 4, 1, 2, 5, 3, 1, 9, 0 };
    std::vector<int> numbers{ -13,  7, -12,  13, -8,  4,  12,  7,  15,  6, -2,  10,  9,  15,  4,  1, -15 };

    int sum = 0;
    std::sort(numbers.begin(), numbers.end());
    {
        //Start with numbers <= 0 
        auto iter1 = numbers.begin(), iter2 = iter1 + 1;
        for (; iter2 != numbers.end() && *iter2 <= 0; iter2 += 2) {
            sum += *iter1 * *iter2;
            iter1 += 2;
            if (iter1 == numbers.end())
                break;
        }
        //Process the 1's
        for (;iter1 != numbers.end() && *iter1 <= 1; ++iter1)
            sum += *iter1;
    }
    {
        //Process numbers > 0 (using a reverse iterator)
        auto iter1 = numbers.rbegin(), iter2 = iter1 + 1;
        for (; iter2 != numbers.rend() && *iter2 > 1; iter2 += 2) {
            sum += *iter1 * *iter2;
            iter1 += 2;
            if (iter1 == numbers.rend())
                break;
        }
        if (iter1 != numbers.rend() && *iter1 > 1)
            sum += *iter1;
    }
    std::cout << sum << std::endl;

    return 0;
}

字符串
我让您添加回所有行,以便将用户输入推送到numbers中。
如果你想知道的话,复杂度是O(n log(n)),因为最初的排序。

相关问题