我想编写一个输入为x
和y
整数值的程序
然后:
array
中。重复:
s
分成两个子集:s1
和s2
。sum1
,sum2
中。sum1 * sum2
的乘积。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;
}
答案 0 :(得分:1)
这不是编程问题,它是组合问题,具有理论上的而不是经验上的解决方案。您只需打印正确的解决方案,而不必在任何分区上进行迭代。
那是为什么?
让
即z是s 1 中所有s元素之和的分数。它认为
,因此两组的乘积都满足:
作为z的函数(不是x和y),这是一个抛物线,在z = 1/2时具有最大值。并且没有其他局部最大值,即接近1/2必然会增加该乘积。因此,您要做的是对整个集合进行分区,以使s 1 和s 2 中的每一个都尽可能接近,以使元素总数达到一半。
通常,您可能不得不使用编程来考虑多个子集,但是由于您的元素是由公式给出的-它是geometric sequence的公式。
首先,假设x> = 2和y> = 2,否则这不是一个有趣的问题。
现在,对于x> = 2,我们知道
(几何序列的总和),因此
即最后一个元素总是胜过所有其他元素。这就是为什么您总是想选择{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)));
}
}