• m个苹果放入n个篮子


    题目 :X个相同的苹果放入Y个篮子,
    (1)篮子可以为空 ,篮子不同。 放法有C(X+Y-1,Y-1 );//
     (2)篮子不可以为空,篮子不同.放法有C(X-1,Y-1) //插挡板法 

           分析有了这个组合公式,参考我的 求组合数 程序即可解决问题。
    (3)篮子可以为空,篮子相同。按上面程序求解 递推公式dp[i][j]=dp[j-i][i]+dp[j][i-1]

    #if 0
    /*
    m个相同的苹果放入n个相同的篮子,篮子可以为空。
    下面两种方法求解,动态规划和递归。但都须知:
    dp[0][j]=0;含义为:j(j>0)个苹果放入0个篮子,没有地方放,放法为0.
    dp[i][0]=1;0个苹果放入i个篮子,每个篮子都为空,放法为1.
    dp[0][0]=1;当然,0个苹果放到0个篮子放法为1.即0!=1;
    还有 dp[i][j],i>j时,即篮子数大于苹果数是dp[i][j]=dp[j][j],含义为 把2个苹果放到5个篮子的放法和把2个苹果放到2个篮子放法数相同。
    */ int dp[100][100];//全局,默认初始化为0 int n,m; int main() { m=5;n=3; int i,j; //全局变量默认初始化为0可以无需初始化了。 // for (j=0;j<m;j++)//苹果 // { // dp[0][j]=0; // } //可以再拆分,也无需初始化。 // for (i=0;i<n;i++)//篮子 // { // dp[i][0]=1; // } dp[0][0] = 1; for(i = 1; i <= n; ++i)//篮子 for( j =0; j <= m; ++j)//苹果 { if(j>=i) { dp[i][j] = dp[i][j-i] + dp[i-1][j]; cout<<"dp["<<i<<"]["<<j<<"] = dp["<<i<<"]["<<j-i<<"] + dp["<<i-1<<"]["<<j<<"]"; cout<<":"<<dp[i][j]<<" = "<<dp[i][j-i]<<" + "<<dp[i-1][j]; } else { dp[i][j] = dp[j][j]; cout<<"dp["<<i<<"]["<<j<<"] = dp["<<j<<"]["<<j<<"]"; cout<<":"<<dp[i][j]<<" = "<<dp[j][j]; } cout<<endl; } cout<<dp[n][m]<<endl; //} return 0; } #endif //递归求解
    #if
    0 int fun(int n,int m)
    {
      if (n==0&&m!=0)//篮子为空
       return 0;
      else if (m==0)
     {
       return 1;   
      }
        else if (m>=n)
        {
       return fun(n,m-n)+fun(n-1,m);
        }
      else
       return fun(m,m);  
     
    }
    int main() { int n=3,m=7; cout<<fun(n,m)<<endl; } #endif

    测试数据: 3 7 count=8
                   3 5 count=5


    (4)篮子不可以为空,篮子相同。没有递推公式:但是dp[X][Y]=dp[X-Y][Y], 计算dp[X-Y][Y]可以用(3)中递推公式。
    下面求解(4)的情况

    //篮子不可以为空,即m>=n;
    int count=0;
    int fun(int n,int m)
    {
        if (n==0&&m!=0)//篮子为空
            count=0;
        else if (m==0)
        {
            count=1;         
        }
        else if (m>=n)
        {
            count=fun(n,m-n)+fun(n-1,m);
        }
        else
            count=fun(m,m);        
        
        return count;    
    }
    
    int main()
    {
        int n=3,m=7;
        fun(n,m-n);
        cout<<count<<endl;
    }
    //测试数据: 3,5 count=2;
    3,7 count=4;

    数学模型为正整数的分拆

    详见组合数学书第二章

    1、C(n,r) 从n个不同的球中取出r个,放进r个相同的 盒子中,不许空盒,有多少种放法.

    2、P(n,r) 从n个不同的球中取出r个,放进r个不相同 的盒子中,不许空盒,有多少种放法.

    3、 r个相同的球放进n个不同的盒子中,允许 空盒,有多少种放法. 正整数的有序拆分

    4 、n个无区别 的球放进r个无区别的盒子,允许空盒。正整数的无序拆分.

    书上公式:

    n拆分为m个无序的数:

                  1                   m=1或n=1

    Q(n,m)= Q(n,n)            m>n

                  1+Q(n,n-1)    m=n

                  Q(n,m-1)+Q(n-m,m)

  • 相关阅读:
    js验证数字
    两个数组的交集 II---简单
    只出现一次的数字---简单
    存在重复---简单
    旋转数组---简单
    买股票的最佳时机 II---简单
    从排序数组中删除重复项---简单
    开始日常一题leetcode
    第二章 Internet地址结构
    2.2线程
  • 原文地址:https://www.cnblogs.com/Yogurshine/p/3829477.html
Copyright © 2020-2023  润新知