整数划分系列问题(动态规划)

今天上算法分析与设计课时,提到整数划分问题,但是因为之前没有很好地理解这一系列的问题。当被老师问到你们做算法的应该会这个问题吧,我当时也不太记得,但是只能硬头皮试着去写了下,用的是brute force,老师果断说我的方法跑不出正确的解,但是课堂上我也没有去解释了。课后自己验证了一下,没有问题,但是看了一下更好的动态规划的解法,顺便把几种整数划分的类型都理解清楚。


原题:一个整数划分为多个数的和,有几种划分的组合。

// 对num划分,最大的数不超过k
int divide(int num, int k) {
    if(num == 0) {
        return 1;
    }
    int res = 0;
    for (int i = k; i > 0; i --) {
        if(num - i >= 0) {
            res += divide(num - i, i);
        }
    }
    return res;
}
这个写法就是枚举了,效率肯定十分慢,不加记忆化的递归也快不到哪去。

加了记忆化后,n稍微大点还是跑不出来。

int d[1000][1000];
// 对num划分,最大的数不超过k
int divide(int num, int k) {
    if(num == 0) {
        return 1;
    }
    if(d[num][k] > 0) {
        return d[num][k];
    }
    int res = 0;
    for (int i = k; i > 0; i --) {
        if(num - i >= 0) {
            d[num-i][i] = divide(num - i, i);
            res += d[num-i][i];
        }
    }
    return res;
}

但是学会整数的划分动归求解,就可以在O(n*n)的时间复杂度内求解!!


下面进入正题。


整数划分问题变型比较多,但是有句话叫做万变不离其宗,这是看了两个贴吧大神(飞机)的讲解后领悟的,所以索性5个整数划分的问题全部列出来,自己也整理一下。

一: 将n划分成若干正整数之和的划分数。
二: 将n划分成k个正整数之和的划分数。
三: 将n划分成最大数不超过k的划分数。
四: 将n划分成若干奇正整数之和的划分数。
五: 将n划分成若干不同整数之和的划分数。

题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=571


引用一下9楼的解释,结合7楼的代码。


先做一个定义:

定义:dp(i, j)表示整数i被划分为j个数的划分数。

那么有dp(i, j) = dp(i - j, j) + dp(i - 1, j - 1)

上述划分数可以分解为两类情况:

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值