DP-划分数

小学期学的算法和做OJ题的各种经验总结

有 n 个无区别的物品 , 将他们分成 不超过 m 堆, 问有多少种分法 ?

  • d i j d_{ij} dij表示将数字i 分成j 份的方案数(初始化 d 0 j = 1 d_{0j}=1 d0j=1,其他为0),有2种类型:
  1. 带0的划分可以少一份。如4 = 0 + 2 + 2 = 2 + 2,把4分成3份 = 把4分成2份

    即把i分成j份 = 把i分成j-1份。所以 d i j d_{ij} dij 包含 d i ,   j − 1 d_{i,\ j-1} di, j1

  2. 不带0的划分,推到带0的划分上,每份均摊少一个1。
    如 5 = 1 + 2 + 2,与 5-3 = 1-1 + 2-1 + 2-1 => 2 = 0 + 1 + 1的效果相同
    即把i分成j份 = 把 i - j 分成j份(每份均摊一个1)。所以 d i j d_{ij} dij包含 d i − j ,   j d_{i-j,\ j} dij, j

  3. 因为每个数只有这两种划分方法,综上, d i j = d i ,   j − 1 + d i − j ,   j d_{ij}=d_{i,\ j-1}+d_{i-j,\ j} dij=di, j1+dij, j

注意边缘条件,如i<j时 d i j d_{ij} dij状态转化为 d i ,   j − 1 d_{i,\ j-1} di, j1

int n,m;
int d[MAXN][MAXM];
int main() {
	d[0][0] = 1;
	for(int i = 1; i <= m; i++) d[0][i] = 1;
	for(int i = 1; i<=n; i++){
		for(int j = 1; j<=m; j++){
			if(i>=j) d[i][j] = d[i][j-1] + d[i-j][j];
			else d[i][j] = d[i][j-1];//份数比数字大,可以降
		}
	}
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值