USACO:子集(低效)
USACO: Subsets (Inefficient)
我正在尝试解决来自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_(数字理论)
在经历了许多编码问题后,我刮出了重复,仍然太慢,所以我回到了原点:(.
现在我更仔细地研究这个问题,看起来我应该试着找到一种方法,不求和,而是通过某种公式直接求和的数量。
如果有人能给我指点如何解决这个问题,我会洗耳恭听的。我用java、C++和python编程。
实际上,有一个更好更简单的解决方案。您应该使用动态编程相反在您的代码中,您将有一个整数数组(其大小为和),其中索引i处的每个值表示可能对这些数字进行分区的方法的数量,以便其中一个分区的和为i。以下是您的代码在C++中的样子:
int values[N];
int dp[sum+1]; //sum is the sum of the consecutive integers
int solve(){
if(sum%2==1)
return 0;
dp[0]=1;
for(int i=0; i<N; i++){
int val = values[i]; //values contains the consecutive integers
for(int j=sum-val; j>=0; j--){
dp[j+val]+=dp[j];
}
}
return dp[sum/2]/2;
}
这给了你一个O(N^3)的解决方案,它对这个问题来说已经足够快了。
我还没有测试过这段代码,所以可能有语法错误或其他什么,但你明白了。如果你还有什么问题,请告诉我。
这与在多项式(x^1+1/x)(x^2+1/x^2)中查找系数x^0项是一样的。。。(x^n+1/x^n),应该取O(n^3)的一个上界。
- 给定一个向量,如何找到该向量的所有子集和的原始索引
- 在子集化后将包含索引号的列表列表映射到标准索引序列
- 显示字符串的集合和子集
- 在程序变得低效之前,允许多少新的[]和删除[]分配是否有限制?
- 证明构造函数体内的辅助是低效的
- 用于子集字符串的 Rcpp 函数
- 为什么我的子集和方法不正确?
- 计算总和为 x 的所有整数子集(包括负数)
- 在尝试使用递归查找集合子集的总数时,我遇到了分割错误
- 从小于或等于某个 N 的数字列表中最小化或找到 n 个理想的子集和
- 使用 Rcpp 的高效矩阵子集
- 返回给定 SEXP 的子集,而无需知道实际的内部数据类型
- 使用递归从子集和中查找最大和
- 如何获得比较两个向量对的子集
- 实现伪多项式DP子集和
- 现代编译器会优化只引用对象子集的局部变量吗
- 类方法子集的惰性评估
- 子集相关位操作
- C++ 特征非连续子集
- USACO:子集(低效)