{^(0),(1),……,()}的部分组的总和

时间:2018-12-11 15:35:21

标签: c++ arrays recursion console combinations

我想编写一个输入为xy整数值的程序 然后:

  1. 设为集合{x 0 1 ,…, y };将其存储在array中。
  2. 重复:

    • 将集合s分成两个子集:s1s2
    • 找到两个子集的每一个的总和,并将它们存储在变量sum1sum2中。
    • 计算sum1 * sum2的乘积。
  3. 程序在遍历所有可能形成的部分组之后结束,然后打印乘积sum1 * sum2的最大值。 示例:假设x = 2,y = 3 s = {1,2,4,8}除法之一是取s1 = {1,4},s2 = {2,8} sum1 = 5,sum2 = 10乘积为50,并将其与以s1 = {1},s2 = {2,4,8} sum1 = 1,sum2 = 14且乘积为14的相同方式计算的其他乘积进行比较。

到目前为止,我的代码:

#include <iostream>
using namespace std;

int main () 
{
    int a[10000]; // Max value expected.
    int x;
    int y;
    cin >> x;
    cin >> y;
    int xexpy = 1;
    int k;

    for (int i = 0; i <= y; i++)
    {
        xexpy = 1;
        k = i;

        while(k > 0)
        { 
            xexpy = xexpy * x;
            k--;
        }

        cout << "\n" << xexpy;
        a[i] = xexpy;
    }

    return 0;
}

2 个答案:

答案 0 :(得分:1)

这不是编程问题,它是组合问题,具有理论上的而不是经验上的解决方案。您只需打印正确的解决方案,而不必在任何分区上进行迭代。

那是为什么?

enter image description here

即z是s 1 中所有s元素之和的分数。它认为

enter image description here

,因此两组的乘积都满足:

enter image description here

作为z的函数(不是x和y),这是一个抛物线,在z = 1/2时具有最大值。并且没有其他局部最大值,即接近1/2必然会增加该乘积。因此,您要做的是对整个集合进行分区,以使s 1 和s 2 中的每一个都尽可能接近,以使元素总数达到一半。

通常,您可能不得不使用编程来考虑多个子集,但是由于您的元素是由公式给出的-它是geometric sequence的公式。

首先,假设x> = 2和y> = 2,否则这不是一个有趣的问题。

现在,对于x> = 2,我们知道

enter image description here

(几何序列的总和),因此

enter image description here

即最后一个元素总是胜过所有其他元素。这就是为什么您总是想选择{x y }作为s 1 和所有其他元素作为s 2 。无需运行任何程序。然后,您还可以轻松计算出最佳的总和。


注意:如果我们不对s的元素进行假设,除了它们是非负整数之外,找到最佳解就是Partition problem的优化版本-它是NP完全的。大致而言,这意味着没有一种解决方案从根本上比仅尝试所有可能的组合要有效得多。

答案 1 :(得分:0)

这里是一个俗气的所有自变量组合生成器,由于我认为这是家庭作业,因此无需评论或解释就可以提供,理解此处的目的和方式是。

#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main(int c, const char **v)
{
    basic_string<const char *> options(v);
    auto N(options.length());
    for (auto n = 1u; n < N; ++n) {
        vector<char> pick(N);
        fill_n(pick.rbegin(), n, 1);
        do for (auto j=1u; j<N; ++j)
            if (pick[j])
                cout << options[j]<<' ';
        while (cout<<'\n', next_permutation(begin(pick)+1, end(pick)));
    }
}