寻找方式的数量

时间:2014-10-03 08:34:03

标签: combinations dynamic-programming combinatorics

给定M位数在1到9之间,通过重复一个或多个给定数字,找到形成N位数的方式的数量,使得每个M位数在N位数中至少存在一次。示例如果M = 3且N = 4答案是36。

解释 - 让三位数为1 2 3我们的N = 4,数字数字可以是1123,3211,1132,.....重复1同样重复2和3我们将得到总ans。

由于答案很大,找到ans%10000000007.1≤M≤N≤100。

1 个答案:

答案 0 :(得分:0)

由于您尚未指定使用哪种编程语言,因此我将使用我喜欢的任何语言(即Java)。如果您更喜欢其他编程语言,可以将我的代码称为伪代码(我在代码中添加了足够多的注释来解释发生了什么)并自行翻译成另一种编程语言。


澄清

在我真正解决问题之前,我想指出输入参数应该是数字集合,而整数N 是至少是 S 的大小。您表达问题的方式似乎表明输入参数是 M N 。这是误导性的,因为如果您考虑S = {1, 1, 3}N = 4,那么很明显,在这种情况下,组合的数量少于您的示例。

高层次的想法

解决这个问题的核心技术(不是那么令人惊讶)动态编程,子问题P(L, T)由两个参数索引:(1)长度{{1}要建造的数量; (2)构造L位数字时必须出现的数字组L。在您的示例中,参数为:(1)T; (2)L = 4

假设现在我们要解决问题T = {1, 2, 3}。让我们从数字字母表中选择一个任意数字P(L, S)(即输入参数a中出现的1到9之间的所有数字)。

  • 如果S位于a,那么 S开头的L位数字由a给出}。

  • 另一方面,如果P(L - 1, S \ {a})a ,那么开头的L位数字的数量> Sa提供。

因此我们有以下公式:

enter image description here

此处Γ表示数字字母,P(L - 1, S)表示S \ {a} = S不在a

此问题的基本案例是SP(0, Ø) = 1表示空集),Ø表示P(L, S) = 0

代码

更新:我已经回滚了我的代码来修改L < |S|(您在问题中使用的模块)的计数,而不是10000000007(减少1个零)。

用Java编写的代码如下:

1000000007