有关计数问题的dp
问题一:划分数
问题描述
有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的更多相关文章
- 有关计数问题的DP 划分数
有n个无差别的物品,将它们划分成不超过m组.求出划分方法数模M的余数. 输入: 3 4 10000 输出: 4(1+1+2=1+3=2+2=4) 定义:dp[i][j] = j的i划分的总数 #inc ...
- POJ 3046 Ant Counting ( 多重集组合数 && 经典DP )
题意 : 有 n 种蚂蚁,第 i 种蚂蚁有ai个,一共有 A 个蚂蚁.不同类别的蚂蚁可以相互区分,但同种类别的蚂蚁不能相互区别.从这些蚂蚁中分别取出S,S+1...B个,一共有多少种取法. 分析 : ...
- [2019杭电多校第一场][hdu6578]Blank(dp)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6578 计数问题想到dp不过分吧... dp[i][j][k][w]为第1-i位置中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 ...
- 【tyvj P4879】骰子游戏
http://www.tyvj.cn/p/4879 首先,投一个骰子,每个数字出现的概率都是一样的.也就是不算小A的话,n个人投出x个骰子需要的次数和点数无关. 计数问题考虑dp,令f(i,j)为前i ...
- Contest1593 - 2018-2019赛季多校联合新生训练赛第三场(部分题解)
H 10255 自然数无序拆分 H 传送门 题干: 题目描述 美羊羊给喜羊羊和沸羊羊出了一道难题,说谁能先做出来,我就奖励给他我自己做的一样礼物.沸羊羊这下可乐了,于是马上答应立刻做出来,喜羊羊见状, ...
- NOIWC前的交流题目汇总
RT 2018.12.27 i207M:BZOJ 4695 最假女选手 以维护最大值为例,记录最大值和严格次大值和最大值的出现次数,然后取min的时候递归到小于最大值但大于次大值修改,这个就是最重要的 ...
- HDU 4832(DP+计数问题)
HDU 4832 Chess 思路:把行列的情况分别dp求出来,然后枚举行用几行,竖用几行.然后相乘累加起来就是答案 代码: #include <stdio.h> #include < ...
- [计数问题dp]子数列的个数
http://www.51nod.com/tutorial/course.html#!courseId=15 解题关键:主要是一种思想 $dp[i] = dp[i - 1]*2$ 如果a[i]不在之前 ...
随机推荐
- lintcode-163-不同的二叉查找树
163-不同的二叉查找树 给出 n,问由 1...n 为节点组成的不同的二叉查找树有多少种? 样例 给出n = 3,有5种不同形态的二叉查找树: 标签 卡特兰数 动态规划 思路 参考博客http:// ...
- shell练习题讲解
写一个脚本,计算100以内所有的奇数的和以及所有偶数的和,分别显示出来#! /bin/bashsum1=0for i in `seq 1 2 100`do sum1=$[$sum1+$i]doneec ...
- sql server 带输入输出参数的分页存储过程(效率最高)
create procedure proc_page_withtopmax( @pageIndex int,--页索引 @pageSize int,--每页显示数 @pageCount int out ...
- C#里面Console.Write()和Console.WriteLine()有什么区别?
Console.Write()和Console.WriteLine()都是System.Console提供的方法,两着主要用来将输出流由指定的输出装置(默认为屏幕)显示出来.两着间的差异在Consol ...
- Jdk1.7 与 jdk1.8的区别,最新的特征有哪些(美团,360,京东面试题目)
在jdk7的新特性方面主要有下面几方面的增强: 1.1二进制变量的表示,支持将整数类型用二进制来表示,用0b开头. 所有整数int.short.long.byte都可以用二进制表示: byte aBy ...
- 使用Windows Live Writer拉取之前写的博客
因为之前写的博客有错误需要修改,但是在Windows Live Writer中找了半天也没找到怎么拉取之前的博客,在[打开本地草稿]或者[打开最近使用过的日志]中,由于存储的项数有限,所以就找不到那篇 ...
- JS面向对象基础讲解(工厂模式、构造函数模式、原型模式、混合模式、动态原型模式)
什么是面向对象?面向对象是一种思想. 面向对象可以把程序中的关键模块都视为对象, 而模块拥有属性及方法. 这样如果我们把一些属性及方法封装起来,日后使用将非常方便,也可以避免繁琐重复的工作. 工厂 ...
- Ansible批量部署工具的安装
1.系统安装gcc,以及python2.6以上(2.6.8): 第一种比较简单的安装方法: 1)直接yum install -y ansible; 2)然后更改配置,/etc/ansible/ansi ...
- Android ListView 显示多种数据类型
ListView往往可能会有不同的数据类型,单类型的数据可能运用会比较少些,这也是最近项目中的一个需求{在发送消息的时候,需要选择联系人,而联系人列表由英文字母索引+联系人组成},上一篇文章只是一个基 ...
- BZOJ5321 & 洛谷4064 & LOJ2274:[JXOI2017]加法——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=5321 https://www.luogu.org/problemnew/show/P4064 ht ...