ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 Excel Home精品图文教程库
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
300集Office 2010微视频教程 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 10121|回复: 20

[讨论] 求整数拆分组合

[复制链接]

TA的精华主题

TA的得分主题

发表于 2011-11-22 22:12 | 显示全部楼层 |阅读模式
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册

发现一个有趣的题目。

来源于以前发放纸币工资时,往往需要准备各种小面额零散币值分给大家,

于是,希望知道对一个整数,到底能拆分成总额相等的多少种组合,产生了兴趣。


题目是这的:

有一笔余额,比如说是438元,那么,可以有多少种不同的纸币组合呢?

比如,可分成,100元4张+20元1张+10元一张+5元1张+2元1张+1元1张=438元,

也可以分成:100元1张+50元3张+10元15张+10元2张+1元18张

甚至直接分成1元438张。



…………
请有兴趣的坛友,编程序列出所有组合解。



题目不算难,关键是看算法。



呵呵。期待高手的简洁高效代码。




最后,数学化重申题目要求是:
对于事先给定的1个整数金额(其取值范围为 1-454元)
求按照 1,2,5,10,20,50,100这7种面值纸币的全部拆分组合。


…………
限定取值范围上限454元,是因为其组合数已经达到65190,再大下去计算的意义不大了。





TA的精华主题

TA的得分主题

发表于 2011-11-22 22:28 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
我也想知道

TA的精华主题

TA的得分主题

发表于 2011-11-22 22:53 | 显示全部楼层
本帖最后由 灰袍法师 于 2011-11-22 22:56 编辑

这个没什么好玩的
《组合数学》有公式直接计算组合总数
1/(1-x^100)/(1-x^50)/(1-x^20)/(1-x^10)/(1-x^5)/(1-x^2)/(1-x)
将上式泰勒展开,展开式中x^454的系数即为组合总数
http://club.excelhome.net/thread-688906-1-1.html 看九楼
当然,编程列举全部的话,又是一堆循环了。。。。。。要速度快还是不容易的。

TA的精华主题

TA的得分主题

 楼主| 发表于 2011-11-22 23:41 | 显示全部楼层
呵呵,我只要编程列举全部就好了。……所以,不用思考很大很大数字的拆分,能拆分小于454的就足够了。



要看代码。

TA的精华主题

TA的得分主题

 楼主| 发表于 2011-11-23 12:25 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
帖子沉的很快啊。

TA的精华主题

TA的得分主题

 楼主| 发表于 2011-11-24 12:36 | 显示全部楼层
自己顶!
  1. Sub DivNum()
  2.     a = Array(1, 2, 5, 10, 20, 50, 100) 'm<=194 (64,443)
  3.    
  4.     m = [m1]
  5.     If m <= 0 Or m > 194 Then
  6.         m = InputBox("m<=194 (64,443):", "Input Sum")
  7.         If m = "" Then Exit Sub Else m = Val(m)
  8.     End If
  9.    
  10.     For n = UBound(a) To 0 Step -1
  11.         If m >= a(n) Then Exit For
  12.     Next
  13.    
  14.     ReDim b(n)
  15.     ReDim c(n + 1, 65535)
  16.     b(0) = m
  17.     For i = n To 1 Step -1
  18.         b(i) = b(0) \ a(i)
  19.         b(0) = b(0) Mod a(i)
  20.     Next
  21.    
  22.     For j = 1 To 65534
  23.         For i = 0 To n
  24.             If b(i) > 0 Then
  25.                 c(i, j) = b(i)
  26.                 c(n + 1, j) = c(n + 1, j) & "+" & a(i) & "*" & b(i)
  27.             End If
  28.         Next
  29. '        Mid(c(n + 1, j), 1, 1) = "="
  30.                
  31.         For i = 1 To n
  32.             If b(i) > 0 Then
  33.                 b(i) = b(i) - 1
  34.                 b(0) = b(0) + a(i)
  35.                 For k = i - 1 To 1 Step -1
  36.                     b(k) = b(0) \ a(k)
  37.                     b(0) = b(0) Mod a(k)
  38.                 Next
  39.                
  40.                 GoTo Nxt
  41.             End If
  42.         Next
  43.         GoTo Ext
  44. Nxt:
  45.     Next
  46.     MsgBox "Over ! ": Exit Sub
  47. Ext:
  48.     For i = 0 To n
  49.         c(i, 0) = a(i)
  50.     Next
  51.     c(n + 1, 0) = j
  52.     ReDim Preserve c(n + 1, j)
  53.     [a1].CurrentRegion.Clear
  54.     [a1].Resize(j + 1, n + 2) = WorksheetFunction.Transpose(c)
  55.    
  56. End Sub
复制代码

TA的精华主题

TA的得分主题

 楼主| 发表于 2012-3-23 16:52 | 显示全部楼层
tianmashi 发表于 2012-3-22 20:25
老师您好,我想麻烦您一下,我有个疑问,附件里的表2是做好的,我想变动一下,程序应该怎么修改呢?

即 ...

代码帮你写好了。实际上没有什么难度。
只要会计算相应数组坐标位置就可以了。
  1. Sub test()
  2.     rw = Cells(65536, Range("data").Column).End(3).Row + 1
  3.     cl = Range("data").End(2).Column - Range("data").Column
  4.     arr = [b2].Resize(rw, cl)
  5.    
  6.     n = Cells(65536, Range("input").Column + 1).End(3).Row - 1
  7.     brr = Range("input").Offset(1, 1).Resize(n, 2)
  8.    
  9.     ReDim crr1(n * 3, 0)
  10.     ReDim crr2(cl * 3 * 3, (rw / 3 - 1) \ 3)
  11.     ReDim k2((rw / 3 - 1) \ 3)
  12.     ReDim crr3(cl * 3 * 39, (rw / 3 - 1) \ 39)
  13.     ReDim k3((rw / 3 - 1) \ 39)
  14.    
  15.     For i = 1 To n
  16.         x = Val(brr(i, 1)) - 1
  17.         y = Val(brr(i, 2))
  18.         t1 = arr(x * 3 + 1, y)
  19.         t2 = arr(x * 3 + 2, y)
  20.         
  21.         crr1(k1, 0) = t1
  22.         crr1(k1 + 1, 0) = t2
  23.         k1 = k1 + 3
  24.         
  25.         j2 = x \ 3
  26.         crr2(k2(j2), j2) = t1
  27.         crr2(k2(j2) + 1, j2) = t2
  28.         k2(j2) = k2(j2) + 3
  29.         
  30.         j3 = x \ 39
  31.         crr3(k3(j3), j3) = t1
  32.         crr3(k3(j3) + 1, j3) = t2
  33.         k3(j3) = k3(j3) + 3
  34.         
  35.     Next
  36.    
  37.     Range("output1").Offset(1, 1).Resize(k1) = crr1
  38.     t2 = Application.Large(k2, 1)
  39.     Range("output2").Offset(1, 1).Resize(t2, UBound(crr2, 2) + 1) = crr2
  40.     t3 = Application.Large(k3, 1)
  41.     Range("output3").Offset(1, 1).Resize(t3, UBound(crr3, 2) + 1) = crr3
  42. End Sub
复制代码

TA的精华主题

TA的得分主题

 楼主| 发表于 2012-3-23 16:53 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
请看附件。

由于文件和代码中使用了范围名称,所以需要使用我的附件。

Table.zip

24.92 KB, 下载次数: 115

TA的精华主题

TA的得分主题

发表于 2012-3-23 13:45 | 显示全部楼层
香川群子 发表于 2011-11-24 12:36
自己顶!

老师,您帮我看看吧。

TA的精华主题

TA的得分主题

发表于 2012-3-22 20:25 | 显示全部楼层
香川群子 发表于 2011-11-24 12:36
自己顶!

老师您好,我想麻烦您一下,我有个疑问,附件里的表2是做好的,我想变动一下,程序应该怎么修改呢?

即由表1,2如何得出表3,4?多谢您了!!

附件如下:

显示名单的转化3.rar (20.27 KB, 下载次数: 23)
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-7-3 03:36 , Processed in 1.066883 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表