1. 程式人生 > >用C語言求組合數

用C語言求組合數

C語言求組合數不能直接使用數學公式C(n,m)=(m!)/(n!*(m-n)!);即使VC 6.0的int是32bit,但其實當計算到17!時候就會溢位,所以需要另闢蹊徑。     先來把公式變形。     (m!)/(n!*(m-n)!)=(m*(m-1)*(m-2)*…*(m-n+2)*(m-n+1))/(n!)=((m-n+1)/1)*((m-n+2)/2)*((m-n+3)/3)*…*((m-n+n)/n)=∏((m-n+k)/k)【k=1,2,3,…,n】 這樣,一項一項的算,就避免了求階乘的路,下面上程式: #include<stdio.h> int main(int argc, char* argv[]) { int isum=1; int m,n,k; scanf("%d%d
",&n,&m);
for(k=1;k<=n;k++) isum=(isum*(m-n+k))/k;//先算乘法,避免先算(m-n+k)/k除不盡帶來誤差 return 0;

}

此方法應該可以用來求catalan數:http://blog.csdn.net/super_chris/article/details/6113779

這些都是我在做ACM題目時考慮的演算法:http://acm.xidian.edu.cn/   

1056題,不過此題此時依然WA. 只能先放一下,明天考科目一,也該看看書了.

相關推薦

C語言合數

C語言求組合數不能直接使用數學公式C(n,m)=(m!)/(n!*(m-n)!);即使VC 6.0的int是32bit,但其實當計算到17!時候就會溢位,所以需要另闢蹊徑。     先來把公式變形。     (m!)/(n!*(m-n)!)=(m*(m-1)*(m-2)

C語言合數C(n,m)

#include<stdio.h> int main() {int n,m;double n1,m1,o1;double fact(int n);printf("Enter n and m

C語言一元二次方根(包括虛根)

#include <stdio.h> #include <math.h> float a,b,c,result; void underZero(){      float part1 = (-1)*b/(2*a);      float part2

C語言出0~999之間的所有“水仙花數”並輸出

執行環境: win10  vs2013 “水仙花數”是指一個三位數,其各位數字的立方和確好等於該數本身,如;153=1+5+3?,則153是一個“水仙花數”。  在數論中,水仙花數(Narcissis

c語言最大公約數和最小z公倍數的函式

1. ```#include<stdio.h> #include<stdlib.h> int fun(int a,int b) { int i,t,n,f; f=a*b; if(a<b) {t=a; a=b; b=t; } while(b!=0) {n=a

c語言實現合數

long long pailie(int a,int b) {     int i;     long long int sum=1;          if(b<a-b)   //c(a,b)=c(a,a-b)  可以減少運算         b=a-b;    

c語言取一個矩陣的最大值及其下標

思想:將矩陣看做一個二維陣列,用scanf()函式輸入矩陣,將陣列首位設定為最大值max,將max與陣列中數按順序兩兩比較,更新max,比較到最後一位得到最終max。void main(){    int a[3][4],i,j,max,max_i,max_j;    pri

PTA-合數C語言

#include<stdio.h> double fact(int num){ double result=num; for(int i=num-1;i>0;i--){ result*=i; } return result; } int main(){

c語言實現合數(帶點優化的思想,防止溢位)

這是大家都知道的組合數,思想也很簡單,但是裡面的階乘,容易溢位,讓m!/n!先約分,減小數的大小,m!/n! = (n+1)(n+2)(n+3)···(m-1)(m); 如果m-n > n的話,我們就讓n = m-n.j儘可能讓乘起來的數小一點。程式碼列印的是25裡

C語言實現:將數A中的內容和數B中的內容進行交換(數一樣大)。

image pri 之前 es2017 sys 變量 ret 只需要 題目 之前我們已經完成了對兩個變量內容進行交換的程序,這兩道題目大同小異,不過是將兩數變成了兩數組。 可能我們會想:我們是不是需要第三個數組作為中間變量進行交換操作? 答案是no,我們只需要通過一個循環體

C#語言編寫:數分析器

find 操作 fin numbers 排序 ole class 數字 輸入 static void Main(string[] args) { #region 創建數組 Console.Write("請輸入數組的

懶癌晚期學圖論的時候自己C語言寫了個可達性矩陣的演算法~

可達性矩陣演算法~ 直接上程式碼 #include <iostream> #include <cstring> using namespace std; #define n 5 void print(int a[n][n]); void print1(int a[n][n]); v

合數C(n,m) % mod的幾種方法

演算法一:乘法逆元,在m,n和mod比較小的情況下適用 乘法逆元:(a/b)% mod = a * b^(mod-2),mod為素數   #include<iostream> #include<cstdio> #include<cmath>

C - Contest Setting Gym -dp合數-種類型01揹包

  C - Contest Setting  Gym - 101982C  題意:最多有1000個不同的數字,代表不同的高度,給出n為n個數(有重複),從n箇中挑出m個不同數字的方案 (不同方案的定義為只要是含有一個不同的數就是不同的方

程式設計C 實驗四 題目四 合數(0082)

Description 輸入n 和r 的值; 當用戶輸入0 0 時,程式結束。 Input 根據公式: C(n,r) = C(n, r-1) * (n - r + 1) / r 輸出運算結果 輸入資料不滿足題意時候,輸

c語言實現數值的最大值。

對於求10個整數中的最大值這類問題,具體分析和解決辦法如下。 第一類:給定一個具體的陣列求陣列中的最大值 程式1: #include<stdio.h> #include<stdlib.h> int main(){ int arr[10] = { 1, 2,

合數(c(m,n))

定義:從n個不同元素中取出m(m≤n)個元素的所有組合的個數,叫做從n個不同元素中取出m個元素的組合數。用符號c(n,m) 表示。性質:c(n,m)=c(n,n-m);  c(n,0)=1; 遞推公

合數的遞迴實現,即C(n,m)

此法借鑑了2009年華為一筆試題我寫的一個遞迴演算法http://blog.csdn.net/challenge_c_plusplus/article/details/6640530排列數的遞迴實現見我的另一篇http://blog.csdn.net/challenge_c_

C語言寫一個數,實現類似JAVA語言中ArrayList的功能

此程式是在看過郝斌老師的資料結構與演算法的視訊後,自己用C語言實現的。整個程式比較簡單,適合入門資料結構時練手。 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #

C語言一個整數的二進位制形式表示中1的個數,函式實現

1:我們知道,整數在計算機中是以補碼的形式儲存的。如果給定一個十進位制正整數是          如何轉換成二進位制數的呢?用的是除以2取餘數的方法。若餘數為1,則1的個數加          1;然後用商再除以2取餘數,直到商為0;但是負數除2的餘數為負數。因此,可以