全国15亿人口中选1000个代表有多少种选法?[1]

[入库:2005年8月18日]  [来源]

本文简介:选择自 northwolves 的 blog

快速组合数c(n,k)=n*(n-1)*(n-2)*...*(n-k+1)/1*2*3*...*k  的求法:



   function zdgys(byval x as long, byval y as long) as long 'get greatest common divisor最大公约数
 
   dim temp as long
    if x > y then temp = x: x = y: y = temp   'let x < y
   do
      temp = y mod x
      if temp = 0 then zdgys = x: exit function
      y = x
      x = temp
  loop
   end function
sub calc(byval n as long, byval k as long, optional byref cnk as string) '计算c(n,k),赋值给cnk
dim xys() as integer, x() as integer, y() as integer, result() as string, i as long, j as long, t as long, temp as long, stimer as double
if n < 0 or n < k then exit sub
stimer = timer
if k = n or k = 1 then cnk = n: goto r '特殊情况
if n > 0 and k = 0 then cnk = 1: goto r '特殊情况
if k > n - k then k = n - k '减少计算量
dim nn() as long, nk() as long
redim nn(1 to k)
redim nk(1 to k)
for i = 1 to k
nn(i) = n + 1 - i ' n*(n-1)*(n-2)*....*(n+1-k)
nk(i) = i ' 1*2*3*...*k
next


for i = k to 1 step -1
             for j = 1 to k
            temp = zdgys(nk(j), nn(i)) '最大公约数
            if temp > 1 then '消除分子分母
               nn(i) = nn(i) / temp
               nk(j) = nk(j) / temp
               end if
            next
next


redim x(1)
redim xys(1)
x(1) = 1 '初始化数组
xys(1) = 1
t = 1


do while not t > k


temp = len(cstr(nn(t)))
redim y(1 to temp)
for i = 1 to temp
y(i) = val(mid(nn(t), temp + 1 - i, 1))
next
redim xys(1 to ubound(x) + ubound(y))
for i = 1 to ubound(x)
for j = 1 to ubound(y)
xys(i + j - 1) = xys(i + j - 1) + x(i) * y(j) '模拟乘法运算
next
next
for i = 1 to ubound(x) + ubound(y) - 1 '进位
temp = xys(i) \ 10
xys(i) = xys(i) mod 10
xys(i + 1) = xys(i + 1) + temp
next
t = t + 1
x = xys
if x(ubound(x)) = 0 then redim preserve x(1 to ubound(x) - 1) '第一位为零则去掉之


loop


redim result(1 to ubound(x)) '逐位赋值
for i = 1 to ubound(x)
result(i) = x(ubound(x) + 1 - i)
next


cnk = join(result, "") '最后结果
r:
debug.print "c(" & n & "," & k & ")=" & cnk & vbcrlf & "用时 "; timer - stimer & " 秒, 结果大约为 " & val(left(cnk, 3)) / 100 & "* 10^" & len(cnk) - 1
erase x() '释放
erase y()
erase xys()
erase result()
erase nn()
erase nk()


end sub



private sub command1_click()
calc 1500000000, 1000
end sub


 


 


c(1500000000,1000)=30652804367164696580061245618584644612627630767867968160482287207505578854118075767413733341865113545827821943234215925381601476838491502713562101051308121811886256344264074095500443454498544782873527381232953591608839778443126863125303594776637408010065945137971003022970106087272779912095118673993148835415545404803408210359936057541641298321398866367630909780954427950260602677841356572015384593028076391922880188863454695625613158555189739103273043693186054292522757402389201949262458783982625369769215639665513120651343627077305247225448215405511745177315577297307995592278944000912129608635572003811892730638646576505559665098287067901804492021447447275828527448463319437263974332506979369648426322521012083011115417734792185803613847776098673007574058102010392545564626748974852860654213922561671313738154819315936146389699558632939168101222776477404052002491162770708016843923192174292119830692530203631071406591557820008413480936874626325481432195805380233658534174129959183937867662826991079111

本文关键:组合 最大公约数 字符串
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top