如何确定循环中的语句将使用条件语句执行多少次

时间:2011-10-08 00:11:28

标签: c# iteration probability

有一个由12个问题组成的测试。每个问题的值必须大于4分。所有问题必须加到100.所有问题都必须有一个整数值。 所以可能的组合可能是5,5,5,5,5,5,5,5,5,5,5,45

理论上会有一种方法可以给出这个结果:

// this method will return the possible number of tests
public static double PosibleNumberOfTests()
{
    int q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11, q12; // each question value

    double counter=0; // if there is a valid combination then counter will be increased by 1

    for (q12 = 5; q12 < 46; q12++)
    {
        for (q11 = 5; q11 < 46; q11++)
        {
            for (q10 = 5; q10 < 46; q10++)
            {
                for (q9 = 5; q9 < 46; q9++)
                {
                    for (q8 = 5; q8 < 46; q8++)
                    {
                        for (q7 = 5; q7 < 46; q7++)
                        {
                            for (q6 = 5; q6 < 46; q6++)
                            {
                                for (q5 = 5; q5 < 46; q5++)
                                {
                                    for (q4 = 5; q4 < 46; q4++)
                                    {
                                        for (q3 = 5; q3 < 46; q3++)
                                        {
                                            for (q2 = 5; q2 < 46; q2++)
                                            {
                                                for (q1 = 5; q1 < 46; q1++)
                                                {
                                                    if (q1 + q2 + q3 + q4 + q5 + q6 + q7 + q8 + q9 + q10 + q11 + q12 == 100)
                                                        counter++;  // here is what we need. How many times will this line be executed!
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

    }
    return counter;
}

请注意,我为每个小于46的值创建了循环,因为如果所有问题的值必须大于4,那么问题就不可能达到50分。例如。

修改

对不起的人我觉得我没有清楚地解释自己。我随机猜测了12个问题。这个例子可能已经有100个问题的测试。我需要的东西就像dlev在评论中提到的那样。我也知道我可以在循环中放置中断以使该方法更有效。如果总和大于100,那么为什么继续循环只是从相应的循环中删除

3 个答案:

答案 0 :(得分:4)

此代码将评估if语句22,563,490,300,366,186,081次。所以不用说,那是行不通的......

但是有一些变化,它会。我并不是说蛮力是解决这个问题的方法,但它确实有效。

首先,为了使表达式更简单,如果每个问题必须具有非负数量的点并且点必须加起来40,请注意他有同样的问题。

现在,第一个循环变为for (q12 = 0; q12 <= 40; q12++)

在第二个循环中,我们不必测试q110之间的所有40,因为q11 + q12不能大于40 }。

因此,第二个循环变为for (q11 = 0; q11 + q12 <= 40; q11++)

等等......

最后,最后一个for循环是完全没必要的,因为q1只有一个可能的值。

所以,改变

for (q1 = 5; q1 < 46; q1++)
    if (q1 + q2 + q3 + q4 + q5 + q6 + q7 + q8 + q9 + q10 + q11 + q12 == 100)
        counter++;

if (q2 + q3 + q4 + q5 + q6 + q7 + q8 + q9 + q10 + q11 + q12 <= 40)
    counter++;

不快。不优雅。但它确实有效。

虽然这比初始实施要快得多,但即使每秒发现1,000,000“好”组合,它仍然需要大约13个小时......

让我们改为问题“每个问题必须至少值1分,所有点的总和必须为52”。这相当于最初的问题。

我们有52分发点。每个星号代表一个点:

****************************************************

为此,我们可以使用分隔符分隔这些点。 11个分隔符将为我们提供12个星号组。

示例:****|*****|****|********|*|***|**|****|****|*********|***|*****

每个分隔符必须位于两个相邻的星号之间。这些空间有51个。

由于分隔符不存在差异,因此解决方案也是问题的解决方案“在11点中可以51项分配多少不同的,与顺序无关的方式。

来自给定11元素集的51 - 组合的数量为51! / ( 40! * 11! ),这为我们提供了47,626,016,970

这一切都假设“秩序很重要”,即例如,如果问题1值10分,问题2值20分,则反之亦然。

对于q个问题,每个问题在测试中的价值超过p分和总共t分,公式为:

(t - p * q - 1)! / ( (t - (p + 1) * q)! * (q - 1)! )

答案 1 :(得分:3)

每当遇到计数问题时,首先减去常数总是一个好主意。在这种情况下,每个问题的最小值为5,因此从每个值和总数中减去该值。这样,每个问题最多可以为40,最少为0。然后在最后,当您提供实际解决方案时,您可以再次添加常量。

现在看看这个问题:Distribution of balls into 'bins with given capacities' using Dynamic Programming

你的问题是一样的,只是它有点简单。它是相同的,因为你的问题对应于箱子,而价值对应于球。

您的问题更简单,因为在您的情况下,问题的能力不受限制。在对上述问题的接受回答中,min(n, c[k])始终等于n

答案 2 :(得分:0)

我老师的答案:(和你们所感谢的一样!)

enter image description here

enter image description here