zoukankan      html  css  js  c++  java
  • 划分问题

    #include <stdio.h>
    /*******************************************************************/
    /*整数划分问题:
    **将正整数n表示成一系列正整数之和:n=n1+n2+…+nk,
    **其中n1>=n2>=…>=nk>=1,k>=1。
    **正整数n的这种表示称为正整数n的划分。求正整数n的不同划分个数。 

    **例如:正整数6有如下11种不同的划分:
    **6;
    **5+1;
    **4+2,4+1+1;
    **3+3,3+2+1,3+1+1+1;
    **2+2+2,2+2+1+1,2+1+1+1+1;
    **1+1+1+1+1+1。
    */
    /************************************************************************/
                                                                         
    /************************************************************************/
    /*算法:
    **记q(n,m)表示n的最大加数n1不大于m的划分个数,则有:
    **       |-    1     ,n=1,m=1
    **q(n,m)=|  q(n,n)   ,n<m
    **       | 1+q(n,n-1),n=m  ,n的划分由n1=n的划分和n1<=n-1的划分组成
    **       |_ q(n-m,m)+q(n,m-1),n>m>1,n的最大加数n1不大于m的划分由n1=m的划分和n1<=m-1的划分组成
    */
    /*******************************************************************/
    int int_partion(int n,int m)
    {
        
    if(n==1||m==1)
            
    return 1;
        
    else if(n<m)
            
    return int_partion(n,n);
        
    else if(n==m)
            
    return 1+int_partion(n,n-1);
        
    else
            
    return int_partion(n-m,m)+int_partion(n,m-1);
    }

    /*非递归算法*/
    #define N 6
    int S[N+1][N+1];
    int int_partion_2(int n,int m)
    {
        
    int i,j;
        
    for (i=1;i<=n;i++)
        {
            S[i][
    1]=1;
            S[
    1][i]=1;
        }
        
    for (i=2;i<=n;i++)
        {
            
    for (j=2;j<=m;j++)
            {
                
    if(i==j)
                    S[i][j]
    =1+S[i][i-1];
                
    else if(i<j)
                    S[i][j]
    =S[i][i];
                
    else
                    S[i][j]
    =S[i-j][j]+S[i][j-1];
            }
        }
        
    return S[n][m];
    }
    /*******************************************************************/
    /*集合划分问题:
    **n个元素{1,2,,n}可以划分为多少个非空子集。该值实际上为Bell数,记为B(n)。
    **例如:{1,2,3}的划分:
    **{{1,2,3}}, {{1,2},{3}}, {{1,3},{2}}, {{1},{2,3}}
    */
    /*******************************************************************/
    /************************************************************************/
    /*算法:
    **记s(n,m)表示n个元素集合可以划分为m个非空子集的数量,该数实际上是Stirling数,则有:
    **s(n,m)=m*s(n-1,m)+s(n-1,m-1); s(n,n+1)=0,s(n,0)=0,s(0,0)=1。
    **显然:B(n)=s(n,1)+s(n+2)++s(n,n)
    */
    /*******************************************************************/

    //计算stirling数
    int stirling(int n,int m)
    {
        
    int min,i,j;
        S[
    0][0]=1;
        
    for (i=1;i<=n;i++)
            S[i][
    0]=0;
        
    for(i=0;i<n;i++)
            S[i][i
    +1]=0;
        
    for (i=1;i<=n;i++)
        {
            
    if(i<m)
                min
    =i;
            
    else
                min
    =m;
            
    for(j=1;j<=min;j++)
                S[i][j]
    =j*S[i-1][j]+S[i-1][j-1];
        }
        
    return S[n][m];
    }

    //计算bell数
    int bell(int n)
    {
        
    int num=0;
        stirling(n,n);
        
    for (int i=1;i<=n;i++)
        {
            num
    +=S[n][i];
        }
        
    return num;
    }
    int main()
    {
        
    int n=4,m=2;
        
    //printf("%d pation numbers are:%d\n",n,int_partion_2(n,n));
        printf("%d,%d sirling number is:%d\n",n,m,stirling(n,m));
        
        printf(
    "%d bell number is:%d\n",n,bell(n));
        
    return 0;
    }
  • 相关阅读:
    POJ 3660 Cow Contest (floyd求联通关系)
    POJ 3660 Cow Contest (最短路dijkstra)
    POJ 1860 Currency Exchange (bellman-ford判负环)
    POJ 3268 Silver Cow Party (最短路dijkstra)
    POJ 1679 The Unique MST (最小生成树)
    POJ 3026 Borg Maze (最小生成树)
    HDU 4891 The Great Pan (模拟)
    HDU 4950 Monster (水题)
    URAL 2040 Palindromes and Super Abilities 2 (回文自动机)
    URAL 2037 Richness of binary words (回文子串,找规律)
  • 原文地址:https://www.cnblogs.com/hustcat/p/1504604.html
Copyright © 2011-2022 走看看