algorithm - 给定从 1 到 k 的数字,选择 d 个数字,它们的总和等于 v
问题描述
我正在尝试查找具有以下属性的集合中不同向量的数量:
- 一个集合是从 1 到 k+1 的 k 个数字
- D是可以选择的元素个数
- V 是元素的总和
例子
k=3,d=3,v=6,结果为7;
<1, 2, 3>, <1, 3, 2>, <2, 1, 3>, <2, 2, 2>, <2, 3, 1>, <3, 1, 2>, <3 , 2, 1>
k=4, d=2, v=7,结果为2;
<3, 4>, <4, 3>
在这种情况下,<2, 5> 无效,因为 5 超过了 k 的值。
我想知道是否有一个数学公式来计算结果。如果没有公式,这个算法的执行效率如何?我发现了一个相当神秘的实现,但我想知道它是否可以改进。
public static int NumberOfDistinctVectors(int k, int d ,int v) {
if((v > k * d) || (v < d)) return 0;
if(d == 1 || v == d) return 1;
if(v == d + 1) return d;
int alpha = 1, beta = 0;
if(1 < v + k - k * d)
alpha = v + k - k * d;
if(k < v - d + 1)
beta = k;
else
beta = v - d + 1;
int sum = 0;
for(int i = alpha; i <= beta; i++) {
sum += NumberOfDistinctVectors(k, d-1, v-i);
}
return sum;
}
解决方案
该问题与以下内容非常相关:
在没有组包含多个对象的组中分配
b
相同对象的组合数是多少?c
n
这是讨论here
想想你的数字是由物体组成的(+1)。所以在你的情况下
- c = d,因为每组对应一个你的数字
- b = vd,因为您需要将至少一个 (+1) 对象放入每个 d 组中
- n = k-1,因为我们假设每个组中已经有一个 (+1) 并且不想变得大于 k
找到下面的代码(使用appache-commons for c(N,K)
)
public static int NumberOfDistinctVectors(int k, int d ,int v) {
return combinations(v-d, d, k-1);
}
//combinations to distribute b identical objects to c groups
//where no group has more than n objects
public static int combinations(int b, int c, int n)
{
int sum = 0;
for(int i = 0; i <= c; i++)
{
if(b+c-1-i*(n+1) >= c-1)
sum += Math.pow(-1, i) * CombinatoricsUtils.binomialCoefficient(c, i)
* CombinatoricsUtils.binomialCoefficient(b+c-1-i*(n+1), c-1);
}
return sum;
}
让我也引用原始答案:
“这是否真的比复发更有用是另一个问题”
推荐阅读
- javascript - 是否可以使用 React 中的 useState() 钩子在组件之间共享状态?
- c - C 程序 - 导致指针崩溃
- batch-file - 批量移动文件到文件夹。文件夹根据文件名命名
- awk - awk 根据另一个匹配和条件更新文件
- python - 在 matplotlib 中使用 pandas timedelta64 作为 x 轴
- java - 重构我必须初始化不同对象的 if 语句
- javascript - Javascript,如果您使用 window.open,如何重定向主页?
- python - 打包 TCP 流
- c - 共享内存 C 题(大小、结构
- python - 如何连接多个列表的元素?