有一个由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,那么为什么继续循环只是从相应的循环中删除
答案 0 :(得分:4)
此代码将评估if
语句22,563,490,300,366,186,081
次。所以不用说,那是行不通的......
但是有一些变化,它会。我并不是说蛮力是解决这个问题的方法,但它确实有效。
首先,为了使表达式更简单,如果每个问题必须具有非负数量的点并且点必须加起来40
,请注意他有同样的问题。
现在,第一个循环变为for (q12 = 0; q12 <= 40; q12++)
。
在第二个循环中,我们不必测试q11
和0
之间的所有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)