USACO:子集(低效)
我正在尝试解决来自 USACO 培训网关的子集...
问题陈述
对于从 1 到 N (1 <= N <= 39) 的许多连续整数集合,可以对集合进行分区分成总和相同的两组。
例如,如果 N=3,则可以用一种方式划分集合 {1, 2, 3},以便两个子集的总和相同:
{3} 和 {1,2} 这算作单个分区(即将顺序计数颠倒为相同的分区,因此不会增加分区的数量)。
如果 N=7,则有四种方法对集合 {1, 2, 3, ... 7} 进行划分,以便每个划分具有相同的总和:
{1,6,7} 和 {2,3,4,5 } {2,5,7} 和 {1,3,4,6} {3,4,7} 和 {1,2,5,6} {1,2,4,7} 和 {3,5,6} 给定 N,您的程序应该打印包含从 1 到 N 的整数的集合可以分为两个总和相同的集合的方式数。如果没有这样的方法则打印 0。
您的程序必须计算答案,而不是从表格中查找答案。
结束
在我通过简单地排列集合并求和来运行 O(N*2^N) 之前。
发现这是多么低效,我继续映射总和序列...... http://en.wikipedia.org/wiki/Composition_(number_theory)
经过多次编码问题来刮掉重复,仍然太慢,所以我回到了第一个:(。
现在我更仔细地研究了这个问题,看来我应该尝试找到一种方法来不求和,但实际上直接去到号码 如果有人能告诉我如何解决这个
问题,我会用 java、C++ 和 python 编程。
I am trying to solve subsets from the USACO training gateway...
Problem Statement
For many sets of consecutive integers from 1 through N (1 <= N <= 39), one can partition the set into two sets whose sums are identical.
For example, if N=3, one can partition the set {1, 2, 3} in one way so that the sums of both subsets are identical:
{3} and {1,2}
This counts as a single partitioning (i.e., reversing the order counts as the same partitioning and thus does not increase the count of partitions).
If N=7, there are four ways to partition the set {1, 2, 3, ... 7} so that each partition has the same sum:
{1,6,7} and {2,3,4,5}
{2,5,7} and {1,3,4,6}
{3,4,7} and {1,2,5,6}
{1,2,4,7} and {3,5,6}
Given N, your program should print the number of ways a set containing the integers from 1 through N can be partitioned into two sets whose sums are identical. Print 0 if there are no such ways.
Your program must calculate the answer, not look it up from a table.
End
Before I was running on a O(N*2^N) by simply permuting through the set and finding the sums.
Finding out how horribly inefficient that was, I moved on to mapping the sum sequences...
http://en.wikipedia.org/wiki/Composition_(number_theory)
After many coding problems to scrape out repetitions, still too slow, so I am back to square one :(.
Now that I look more closely at the problem, it looks like I should try to find a way to not find the sums, but actually go directly to the number of sums via some kind of formula.
If anyone can give me pointers on how to solve this problem, I'm all ears. I program in java, C++ and python.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这与在多项式 (x^1+1/x)(x^2+1/x^2)...(x^n+1/x^n) 中查找系数 x^0 项是一样的,其上限约为 O(n^3)。
This is the same thing as finding the coefficient x^0 term in the polynomial (x^1+1/x)(x^2+1/x^2)...(x^n+1/x^n), which should take about an upper bound of O(n^3).
实际上,有更好、更简单的解决方案。您应该使用动态编程
反而。在您的代码中,您将有一个整数数组(其大小为总和),其中索引 i 处的每个值表示可能对数字进行分区的方法数,以便其中一个分区具有i 的总和。您的代码在 C++ 中可能如下所示:
这为您提供了一个 O(N^3) 解决方案,对于此问题而言,它的速度足够快。
我还没有测试过这段代码,所以可能存在语法错误或其他错误,但你明白了。如果您还有其他问题,请告诉我。
Actually, there is a better and simpler solution. You should use Dynamic Programming
instead. In your code, you would have an array of integers (whose size is the sum), where each value at index i represents the number of ways to possibly partition the numbers so that one of the partitions has a sum of i. Here is what your code could look like in C++:
This gives you an O(N^3) solution, which is by far fast enough for this problem.
I haven't tested this code, so there might be a syntax error or something, but you get the point. Let me know if you have any more questions.