zoukankan      html  css  js  c++  java
  • 小球装箱问题八连(组合数学)

    n个球不可区分,m个盒子不可区分:

    盒子不可为空:dp[n][m]= dp[n-m][m]+ dp[n-1][m-1]

    盒子可为空:dp[n+m][m]= dp[n][m]+ dp[n+m-1][m-1]

    对于盒子不可以为空的时候:

    int dp[100][100]={0};
    dp[1][1]=1;
    for(int i=2;i<=n;i++){
        for(int j=1;j<=n;j++){
            dp[i][j]=dp[i-j][j]+dp[i-1][j-1];
        }      
    }

    这里解释一下这个递推式,dp[i][j]的方案数中分两类一类是方案中包含1的,一类是不包含1的:

      1.包含1的由于一定分解1,所以这一类的答案等价于求dp[i-1][j-1];

      2.由于一定不分解出1,所以我们反向思考如果在dp[i-m][[j]的所有方案数上全部加上1,这样所有方案数不就存在1了吗?而且和还是i。

    对于盒子可以为空的时候:

      我们假设可以现在每个盒子里面放一个球,也就是总球数是n+m个球,放进m个盒子里面,然后我在从每个盒子里面拿走一个小球,不就是盒子可以为空的情况了吗?所以我们可以把这个问题转化为求上面式子中的dp[n+m][m]=dp[n][m]+dp[n+m-1][m-1];

    n个球不可区分,m个盒子可区分:

    方法:隔板法

    盒子不可为空:C(n-1,m-1)
    盒子可为空:C(n+m-1,m-1)

    盒子不可以为空:

    由于球是不可区分,盒子是可以区分,我们可以采用上述的隔板法(在高中应该学过了),n个小球有n-1个间隙,现在分成m个集合,需要插入m-1个隔板,不就是C(n-1,m-1)吗?

    盒子可以为空:

      同样的套路我们可以先在每个盒子里面放一个小球,需要m个,然后把问题转化为上面不可为空的情况。

    n个球可区分,m个盒子不可区分:

    方法:第二类斯特林数
    盒子不可为空:第二类斯特林数 S[n][m]
    盒子可为空:第二类斯特灵数求和 ΣS[n][m](假设一个为空,两个为空,三个为空……说白了不就是求和吗?)

    第二类斯特林数的定义:表示将n个不同的元素拆分成m个集合的方案数

    求第二类斯特林数的代码:

    1 for(II i=0;i<N;i++){
    2         S[i][i]=1;
    3         if(i>=1) S[i][0]=0;
    4         for(II j=1;j<i;j++) 
    5             S[i][j]=(j*S[i-1][j]+S[i-1][j-1]+mod)%mod;
    6     }

    n个球可区分,m个盒子可区分

    盒子不可为空:第二类斯特林数*阶乘数 S[n][m]*A[m]
    盒子可以为空:m^n

    由于盒子可以区分了,所以直接乘一个阶乘数就可以了,至于盒子可以为空的时候,每个球有m中选择,所以答案是m^n次方

    其他和整数划分有关的问题:

      1.将n划分成最大数不超过k的划分数(完全背包物品1-k,背包容量n)

      2. 将n划分成若干奇正整数之和的划分数(完全背包物品小于n的奇数,背包容量为n)

      3. 将n划分成若干不同整数之和的划分数(0-1背包物品1-n,背包容量为n)

  • 相关阅读:
    android 打包错误
    mysql innoDB 挂了的临时解决方案
    android notification 传值关键
    maven eclipse 插件下载地址
    微信html5开发选哪一个
    android AsyncTask 只能在线程池里单个运行的问题
    关于Fragment 不响应onActivityResult的情况分析 (
    Android-BaseLine基础性开发框架
    linux网络流量实时监控工具之iptraf
    android 圆角按钮和按钮颜色
  • 原文地址:https://www.cnblogs.com/xiaowuga/p/7623074.html
Copyright © 2011-2022 走看看