问题一:划分数

问题描述

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

我们定义dp[i][j],表示j的i划分的总数

将j划分成i个的话,可以先取出k个,然后将剩下的j-k个分成i-1份。

考虑n的m划分Ai,如果对于每一个i都有Ai>0,那么Ai-1就对应了n-md的m划分。另外如果存在Ai=0,那么就对应了n的m-1划分,则可以得到递推公式:

a[i][j]=a[i][j-i]+a[i-1][j];

#include<iostream>
#include<stdio.h>
#define MAX_M 100
#define MAX_N 100
using namespace std;
int n,m,M;
int dp[MAX_M+1][MAX_N+1];///dp[i][j]表示j的i划分的总数
void solve()
{
dp[0][0]=1;
for(int i=1; i<=m; i++)
{
for(int j=0; j<=n; j++)
{
if(j-i>=0)
dp[i][j]=(dp[i-1][j]+dp[i][j-i])%M;
else
dp[i][j]=dp[i-1][j];
}
}
printf("%d\n",dp[m][n]);
}
int main()
{
scanf("%d%d%d",&n,&m,&M);
solve();
return 0;
}

问题二:多重集组合数

问题描述:

有n种物品,第i种物品有Ai个。不同种类的物品可以互相区分,但相同种类的无法区分。从这些物品中取出m个的话,有多少种取法?求出方案数模M的余数。

分析:

为了不重复计数,同一种类的物品最好一次性处理好。

定义dp[i+1][j],表示从前i种物品中取出j个的组合总数

从前i种物品中取出j个,可以从前i-1种产品中取出j-k个,再从第i种产品中取出k个

#include<iostream>
#include<stdio.h>
#define MAX_M 100
#define MAX_N 100
using namespace std;
int n,m,M;
int a[MAX_N];
int dp[MAX_M+1][MAX_N+1];
void solve()
{
///不管从多少种物品中取,取0个的方法有且仅有1种
for(int i=0; i<=n; i++)
dp[i][0]=1;
for(int i=0; i<n; i++)
for(int j=1; j<=m; j++)
{
if(j-1-a[i]>=0)///加个M避免减法过后产生负数
dp[i+1][j]=(dp[i+1][j-1]+dp[i][j]-dp[i][j-1-a[i]]+M)%M;
else
dp[i+1][j]=(dp[i+1][j-1]+dp[i][j])%M;
}
printf("%d\n",dp[n][m]);
}
int main()
{
scanf("%d%d%d",&n,&m,&M);
for(int i=0; i<n; i++)
scanf("%d",&a[i]);
solve();
return 0;
}

有关计数问题的dp的更多相关文章

  1. 有关计数问题的DP 划分数

    有n个无差别的物品,将它们划分成不超过m组.求出划分方法数模M的余数. 输入: 3 4 10000 输出: 4(1+1+2=1+3=2+2=4) 定义:dp[i][j] = j的i划分的总数 #inc ...

  2. POJ 3046 Ant Counting ( 多重集组合数 && 经典DP )

    题意 : 有 n 种蚂蚁,第 i 种蚂蚁有ai个,一共有 A 个蚂蚁.不同类别的蚂蚁可以相互区分,但同种类别的蚂蚁不能相互区别.从这些蚂蚁中分别取出S,S+1...B个,一共有多少种取法. 分析 :  ...

  3. [2019杭电多校第一场][hdu6578]Blank(dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6578 计数问题想到dp不过分吧... dp[i][j][k][w]为第1-i位置中4个数最后一次出现的 ...

  4. 洛谷 P7620 - CF1431J Zero-XOR Array(状压 dp)

    洛谷题面传送门 首先显然题目等价于求有多少个长度 \(n-1\) 的序列 \(b\) 满足 \(a_i\le b_i\le a_{i+1}\),满足 \(b_1\oplus b_2\oplus\cdo ...

  5. 【tyvj P4879】骰子游戏

    http://www.tyvj.cn/p/4879 首先,投一个骰子,每个数字出现的概率都是一样的.也就是不算小A的话,n个人投出x个骰子需要的次数和点数无关. 计数问题考虑dp,令f(i,j)为前i ...

  6. Contest1593 - 2018-2019赛季多校联合新生训练赛第三场(部分题解)

    H 10255 自然数无序拆分 H 传送门 题干: 题目描述 美羊羊给喜羊羊和沸羊羊出了一道难题,说谁能先做出来,我就奖励给他我自己做的一样礼物.沸羊羊这下可乐了,于是马上答应立刻做出来,喜羊羊见状, ...

  7. NOIWC前的交流题目汇总

    RT 2018.12.27 i207M:BZOJ 4695 最假女选手 以维护最大值为例,记录最大值和严格次大值和最大值的出现次数,然后取min的时候递归到小于最大值但大于次大值修改,这个就是最重要的 ...

  8. HDU 4832(DP+计数问题)

    HDU 4832 Chess 思路:把行列的情况分别dp求出来,然后枚举行用几行,竖用几行.然后相乘累加起来就是答案 代码: #include <stdio.h> #include < ...

  9. [计数问题dp]子数列的个数

    http://www.51nod.com/tutorial/course.html#!courseId=15 解题关键:主要是一种思想 $dp[i] = dp[i - 1]*2$ 如果a[i]不在之前 ...

随机推荐

  1. QT分析之调试跟踪系统

    原文地址:http://blog.163.com/net_worm/blog/static/127702419201002004518944/ 在我们前面的分析中,经常看到qWarning()和qDe ...

  2. html5 isPointInPath相关操作

    <body> <canvas id="> </canvas> <script type="text/javascript"> ...

  3. BZOJ 1821 部落划分(二分+并查集)

    答案是具有单调性的. 因为最近的两个部落的距离为mid,所以要是有两个野人的距离<mid,则他们一定是一个部落的. 用并查集维护各联通块,如果最后的联通块个数>=k,那么mid还可以再小点 ...

  4. BZOJ 1816 扑克牌(二分)

    由于答案具有单调性,考虑二分答案并验证. 如果能凑齐x堆,因为每个joke在一个牌堆里最多只能用一次,则至多只能用min(x,m)个joke. 对于每个牌,如果这个牌的总数小于x,用joke补齐剩下的 ...

  5. Django 2.0 学习(07):Django 视图(进阶-续)

    接Django 2.0 学习(06):Django 视图(进阶),我们将聚焦在使用简单的表单进行处理和精简代码. 编写简单表单 我们将用下面的代码,来替换之前的detail模板("polls ...

  6. poj2018——Best Cow Fences

    Description Farmer John's farm consists of a long row of N (1 <= N <= 100,000)fields. Each fie ...

  7. Dom-直接 /间接选择器

    Dom:Document Object Model的缩写, 把html转换成了文本对象. 1. 直接选择器 1.直接查找 document.getElementById 根据ID获取一个标签 docu ...

  8. 【题解】JXOI2017颜色

    一眼线段树...显然,我们可以考虑最后所留下的区间,那显然这个区间中应当不能存在任何与区间外相同的颜色.这里的转化也是很常用的,我们用 \(nxt[i]\) 表示与 \(i\) 颜色相同的下一个位置在 ...

  9. 51NOD 1149:Pi的递推式——题解

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1149 F(x) = 1 (0 <= x < 4) F(x) ...

  10. NOIP2017金秋冲刺训练营杯联赛模拟大奖赛第二轮Day2题解

    肝了两题... T1一眼题,分解质因数,找出2的个数和5的个数取min输出 #include<iostream> #include<cstring> #include<c ...