给定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。
答案 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位数字的数量> S
由a
提供。
因此我们有以下公式:
此处Γ表示数字字母,P(L - 1, S)
表示S \ {a} = S
不在a
。
此问题的基本案例是S
(P(0, Ø) = 1
表示空集),Ø
表示P(L, S) = 0
。
更新:我已经回滚了我的代码来修改L < |S|
(您在问题中使用的模块)的计数,而不是10000000007
(减少1个零)。
用Java编写的代码如下:
1000000007