简单的划分数

25 篇文章 0 订阅
2 篇文章 0 订阅

问题

划分数就是将整数 n 分成若干个大于 0 的数的和。例如,n = 4,可以分成 1+1+1+1,1+1+2,1+3,2+2,4,一共 5 种方案,注意 1+1+2,1+2+1,2+1+1被认为是相同的方案。

求整数 80 的划分数方案。


答案

15796476


思路

还是用dfs做,只是有点慢(要25s)( ̄▽ ̄)”(只适合小数,如果是大数的话就很慢了)。

也可以用递归做,将递归函数的声明为 int d(int n, int m);其中n为要划分的正整数,m是划分中的最大加数(当m > n时,最大加数为n),分下列几种情况:

  • 当 n=1,d为1,因为无论m为多少就只有1
  • 当 m=1 时,d=1 ,由上例可知,当 n=4 时,d只有 1+1+1+1 这1种
  • 当 n=m 时,又分为两种情况:

    • 第一种就是包含m的时候,就只有 m 这一种。
    • 另外一种就是不包含 m ,那么最大数就为 m-1 ,有 d(n,m-1) 种

    因此当 n=m 时,d(n , n)=1+ d(n,n-1)

  • 当n < m 就相当于 d(n,n) 了

  • 当 n > m 时,一种是不含m,为d(n,m-1)种,一种是含有m,有d(n-m,m)种

    因此d(n,m)=d(n-m,m)+d(n,m-1)

    注意理解d(n-m,m),注意这里的前提是划分包含m,所以将m提出来一个,保证划分中一定会有m,剩下数字划分的和为n-m,而这n-m中可能不会出现m,也可能出现m,但由于我们已经提出了一个m,所以此处不用担心m是否再出现。第一个数为什么是(n-m),原因是提出一个m后,已经保证了划分中一定出现m,而n-m还没有进行划分,这里忽略提出的m,对剩下的整数n-m进行划分,划分的最大值仍然是m


代码

  • dfs代码
#include <iostream>
using namespace std;
int total=0;
void dfs(int a,int sum){
    if (sum==80) {
        total++;
        return;
    }
    if (sum>80) {
        return;
    }
    for (int i=a;i<=80;i++) {
        dfs(i,sum+i);
    }
}
int main(int argc, char *argv[]) {
    dfs(1,0);
    printf("%d",total);
    return 0;
}
  • 递归代码
#include <stdio.h> 
int d(int n, int m){
    if(n < 1 || m < 1) return 0;
    if(n == 1 || m == 1) return 1;
    if(n < m) return d(n, n);
    if(n == m) return (d(n, m - 1) + 1);
    if(n > m) return d(n, m - 1)+d((n - m), m);
}
int main(){
    printf("%d",d(80,80));
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值