• n的m划分递推


    http://www.hankcs.com/program/m-n-recursive-division.html

    有n个无区别的物品,将它们划分为不超过m组,求出划分方法数模M的余数。

    限制条件:

    1≤m≤n≤1000

    2≤M≤10000

    输入

    n = 4

    m = 3

    M = 10000

    输出:

    4 (1 + 1 + 2 = 1 + 3 = 2 + 2 = 4)

    这样的划分被称作n的m划分,特别的,m = n时被称作n的划分数。在此我们定义如下:

    dp[i][j] = j 的 i 划分的总数

    递推关系的难点在于不重复。我们采用一种标准将问题化为子问题,这个标准需要用到一种新的定义。我们定义n的m划分具体为一个集合{ai},{ai}满足∑mi=1 ai = n 。可以看出{ai}里一共有m个数,这m个数不一定大于0。

    这个标准是:是否存在某个ai=0;这样可以将{ai}分为两种情况:

    1、不存在某个ai=0

    此时{ai}的个数等于{ai – 1}的个数,即 n – m 的 m 划分。理解起来并不难,集合里每个数都减去1,一共减了m个。

    此时dp[i][j] = dp[i][j – i] 。

    2、存在某个ai=0

    此时{ai}的个数等于 n 的 m – 1 划分。可以这样思考,存在ai=0,说明划分一定不足m组,那么至少可以少分一组同时满足划分数相同。

    此时dp[i][j] = dp[i – 1][j] 。

    那么{ai}总的划分数就是这两种情况的综合,dp[i][j] = dp[i][j – i] + dp[i – 1][j]。

     1 int n, m;
     2 int dp[MAX_M + 1][MAX_N + 1];
     3 void solve()
     4 {
     5     dp[0][0] = 1;
     6     for(int i = 1; i <= m; i++)
     7     {
     8         for(int j = 0; j <= n; j++)
     9         {
    10             if(j - i >= 0)
    11                 dp[i][j] = (dp[i - 1][j] + dp[i][j - 1]) % M;
    12             else
    13                 dp[i][j] = dp[i - 1][j];
    14         }
    15     }
    16 }
  • 相关阅读:
    css 样式库
    css命名规则
    css选择器
    清除浏览器自带样式
    导航菜单制作
    清除浮动和样式重置快捷代码
    程序练习网站
    各种布局样式模板
    使用gulp解决外部编辑器修改Eclipse文件延迟刷新
    jQuery Validate 表单验证 — 用户注册简单应用
  • 原文地址:https://www.cnblogs.com/CZT-TS/p/8633530.html
Copyright © 2020-2023  润新知