zoukankan      html  css  js  c++  java
  • 一般的排列组合计数公式

     在n个不同的元素中:

        若取 r 个按次序排列, 则成为从n中取r个排列,其排列数为:P( n, r )=( n! ) / ( n-r )!  。

        如取出 r 个二不考虑起次序,则称为 从n中取 r 个组合, 其组合数为:C( n, r ) = ( n! )/[ ( r! ) *( n-r )! ] 。

     进行阶乘运算的数值较大, 直接计算分子和分母的话,效率低切容易溢出。

       一 : 采取:连乘 r 个整商法

           C( n, r ) = [ (n-r-1) / r ] * [ (n-r-2)/(r-1) ] * ..........* [ n / 1 ]  .

      二: 二项式洗漱公式法

          C( j, i ) =  C( j, i-1) + C(j-1, i-1 ) .

         通过 i, j 的双重循环直接递推 c[i][j] ;

      样题:

      POJ  2249

            因为常用blockcodes编译代码,所以对于大的数据类型会选择 long long,  对于这道题,用了__int64类型(因为不常用,所以不能出错)

           复习一下:定义 __int64 ( 双下划线+int+64 )   输出:printf("I64d ", a);     I64d    !!!!

           

    Binomial Showdown
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 18112   Accepted: 5514

    Description

    In how many ways can you choose k elements out of n elements, not taking order into account? 
    Write a program to compute this number.

    Input

    The input will contain one or more test cases. 
    Each test case consists of one line containing two integers n (n>=1) and k (0<=k<=n). 
    Input is terminated by two zeroes for n and k.

    Output

    For each test case, print one line containing the required number. This number will always fit into an integer, i.e. it will be less than 231
    Warning: Don't underestimate the problem. The result will fit into an integer - but if all intermediate results arising during the computation will also fit into an integer depends on your algorithm. The test cases will go to the limit. 

    Sample Input

    4 2
    10 5
    49 6
    0 0
    

    Sample Output

    6
    252
    13983816
    

    Source

     
         采用 分整式连乘的方法
          
        C ( n, k ) = (n-k+1)/k  *   (n-k+2)/(k-1)  * ......  * ( n)/1  .
     
     
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    __int64 work(__int64 n, __int64 k)
    {
    	if(k>n/2)
    		k = n-k; //减少枚举量(剪枝)
    __int64 a=1, b=1; //代表分子和分母 int i; for(i=1; i<=k; i++) //循环k次运算 { a=a*(n-i+1); //分子 b=b*i; if(a%b==0) //说明能整除,进行整数商处理 { a=a/b; b=1; } } return a/b; } int main() { int n, k; while(scanf("%d %d", &n, &k)!=EOF) { if(n==0 ) { break; } printf("%I64d ", work(n, k) ); } return 0; }

      

  • 相关阅读:
    五分钟上手Markdown
    css中居中方法小结
    事务和同步锁
    插入排序
    插入排序
    交换排序
    eclipse 常用快捷键
    交换排序
    二叉搜索树(BST)
    二叉树遍历以及根据前序遍历序列反向生成二叉树
  • 原文地址:https://www.cnblogs.com/yspworld/p/3996366.html
Copyright © 2011-2022 走看看