生成供应有限的组合/数字组列表

发布于 2024-11-24 19:58:22 字数 1459 浏览 0 评论 0原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

帅气称霸 2024-12-01 19:58:22

其次,我建议采用生成函数方法。

  • 红球的数量可以是:0,1
  • 蓝球的数量可以是:0,1
  • 黄球的数量可以是:0,1 ,2
  • 绿球的数量可以是:0,1,2,3

因此你想展开下面的多项式

(1 + x) * (1 + x) * (1 + x + x^2) * (1 + x + x^2 + x^3)

并看看x^3的系数code> 因为您总共需要 3球。

这将为您提供执行此操作的多种方法,以及获取系数的方法(从每个括号表达式中取出一项)将告诉您如何进行组合。这是有效的,因为选择 01 红球与从第一项 1x 中选择相同分别为 code>(1 + x),类似地选择 i 绿球意味着从最后一项中选择项 x^i。那么选出的球总数就是指数之和。由于您想要 3 个球,因此您应该查看该多项式展开时 x^3 的系数:

1 + 4x + 8x^2 + 11x^3 + 11x^4 + 8x^5 + 4x^6 + x^7

因此,有 11 种可能的组合给定组中的 3 个球。

要迭代可能性,您只需按顺序从表达式中选择一个术语:

int count = 0;
for (int r=0; r<=1 && r<=3; ++r) {
    for (int b=0; b<=1 && r+b<=3; ++b) {
        for (int y=0; y<=2 && r+b+y<=3 ; ++y) {
            for (int g=0; g<=3 && r+b+y+g==3; ++g) {
                count++;
                printf("   red: %d\n  blue: %d\nyellow: %d\n green: %d",r,b,y,g);
            }
        }
    }
}
return count;

前两个 for 循环中的第二个条件(r<=3r +b<=3) 在此示例中是不必要的,但我将其保留下来是为了说明如何概括该问题。

On second though, I suggest a generating function approach.

  • The number of red balls can be: 0,1
  • The number of blue balls can be: 0,1
  • The number of yellow balls can be: 0,1,2
  • The number of green balls can be: 0,1,2,3

Therefore you want to expand the following polynomial

(1 + x) * (1 + x) * (1 + x + x^2) * (1 + x + x^2 + x^3)

and look at the coefficient of x^3 because you want a total of 3 balls.

This will give you the number of ways to do it, and the way to get the coefficient, taking one term from each parenthesized expression, will tell you how to do the combinations. This works because choosing 0 or 1 red ball is the same as choosing 1 or x from the first term (1 + x), respectively, and similarly choosing i green balls means choosing the term x^i from the last term. Then the total number of balls selected is the sum of the exponents. Since you want 3 balls, you should look at the coefficient of x^3 when this polynomial is expanded:

1 + 4x + 8x^2 + 11x^3 + 11x^4 + 8x^5 + 4x^6 + x^7

Therefore there are 11 possible combinations of 3 balls from the given set.

To iterate the possibilities, you can just choose a term from the expressions in order:

int count = 0;
for (int r=0; r<=1 && r<=3; ++r) {
    for (int b=0; b<=1 && r+b<=3; ++b) {
        for (int y=0; y<=2 && r+b+y<=3 ; ++y) {
            for (int g=0; g<=3 && r+b+y+g==3; ++g) {
                count++;
                printf("   red: %d\n  blue: %d\nyellow: %d\n green: %d",r,b,y,g);
            }
        }
    }
}
return count;

The second conditions in the first two for loops (r<=3 and r+b<=3) are unnecessary in this example, but I left it in to illustrate how the problem could be generalized.

阳光下慵懒的猫 2024-12-01 19:58:22
generate_combinations(a1, a2, a3, a4, c1, c2, c3, c4)
1. if a1 + a2 + a3 + a4 = 3 then print (a1, a2, a3, a4)
2. else then
3.    if c1 > 0 then generate_combinations(a1+1, a2, a3, a4, c1-1, c2, c3, c4)
4.    if c2 > 0 then generate_combinations(a1, a2+1, a3, a4, c1, c2-1, c3, c4)
5.    if c3 > 0 then generate_combinations(a1, a2, a3+1, a4, c1, c2, c3-1, c4)
6.    if c4 > 0 then generate_combinations(a1, a2, a3, a4+1, c1, c2, c3, c4-1)

或者类似的东西。不过,这不会捕获重复项...不过,我想您可以添加更多逻辑来过滤掉这些重复项。也许是后期处理?

一些澄清:这是通过计数(1)你手中的球和(2)袋子中的球来实现的。它确保每种颜色的手+包=原装。最初空手调用它,它会打印出您手中可以有三个球的所有方式。

如果您确实想确保该算法仅给出唯一的球(而不是将其与算法结合使用以从列表中删除重复项),则可以确保您不会将任何例如红球添加到您的手上,如果您已经添加了任何高阶球(即,如果 a2 > 0 且 a1 = 0,则无需添加任何红色)。

generate_combinations(a1, a2, a3, a4, c1, c2, c3, c4)
1. if a1 + a2 + a3 + a4 = 3 then print (a1, a2, a3, a4)
2. else then
3.    if c1 > 0 then generate_combinations(a1+1, a2, a3, a4, c1-1, c2, c3, c4)
4.    if c2 > 0 then generate_combinations(a1, a2+1, a3, a4, c1, c2-1, c3, c4)
5.    if c3 > 0 then generate_combinations(a1, a2, a3+1, a4, c1, c2, c3-1, c4)
6.    if c4 > 0 then generate_combinations(a1, a2, a3, a4+1, c1, c2, c3, c4-1)

Or something like that. That won't catch duplicates, though... I suppose you could add some more logic to filter those out, though. Maybe post-processing?

Some clarification: this works by keeping counts of (1) the balls in your hand and (2) the balls in the bag. It ensures that hand+bag=original for every color. Call it with an initially empty hand and it will print every way you can have three balls in your hand.

If you really want to make sure that the algorithm only gives unique ones (rather than using this in conjunction with an algorithm to remove duplicates from a list), you can make sure that you don't add any e.g. red balls to your hand if you have already added any higher-order balls (i.e., if a2 > 0 and a1 = 0, then you don't need to add any red).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文