简单整数规划问题(递归和动态规划)

# 简单整数规划问题(递归和动态规划)

### 前言

哈喽大家好,欢迎来到我的个人公众号~创建这个公众号的目的呢,是为了记录平时的所学所写,也是对所学知识的一次巩固,同时还能督促自己学习。之前也有写过一些东西,不过是在[我的CSDN](https://my.csdn.net/)上. BY THE WAY, 我个人对机器学习比较感兴趣,如果大家有什么好的想法也可以与我分享哟~让我们开始吧。

___

本周算法课上老师留了一个作业,要求用动态规划的方法去求解下面这样一个问题:

>【问题描述】将正整数n表示成一系列正整数之和,n=n1+n2+…+nk, 其中n1>=n2>=…>=nk>=1 ,k>=1 。正整数n的这种表示称为正整数n的划分。正整数n的不同的划分个数称为正整数n的划分数。

输入

标准的输入包含若干组测试数据。每组测试数据是一个整数N(0 < N <= 50)。

【输出】

对于每组测试数据,输出N的划分数。

样例输入

5

6

7

【样例输出】

7

11

15

【提示】

5, 4+1, 3+2, 3+1+1, 2+2+1, 2+1+1+1, 1+1+1+1+1

### Solution:

这题挺简单的,对吧?观察上面的提示,从左到右,分解的式子中,最大的数为5,4,3,2,1.是的,只要按照它分解的数字中最大的那个数从大到小排列(即划分中最大的整数从大到小排列),依次求解就OK了。

这明显是一个递归求解的问题,我们假设递归函数签名为`int f(int m,int n)`,于是可以将原问题大致分为有两种情况: 

* 划分中包含m 

* 划分中不包含m

举个栗子,如f(5,4),如果划分中包含4,也就相当于剩下了1还没划分,我们再去划分1即可;

如果不包含4,那么就令m=m-1, 即f(n,m)=f(n-m,m)+f(n,m-1)。由于不会出现负数划分,所以可能出现f(n-m,m)中,第一个参数比第二个小的情况,简单地令两个参数都为第一个即可

当然,还有很重要的一点,递归的边界是什么?So easy,当m、n任意一个是1,那肯定只有一种划分情况;当划分中的最大数等于本身时,也只有一种情况。

### 递归代码

“`c++

int f(int n,int m)

{

//  参数n为要划分的目的数,m为划分中的最大整数

if (n == 1 || m == 1)  return 1;

if (n == m)

return f(n, m – 1) + 1;  // 这里的1代表{n}这个自身划分

if (n < m)

return f(n, n);

else

{

return f(n – m, m) + f(n, m – 1);

}

}

“`

### 稍加思索

稍微看一眼我们就能发现,这个算法的效率并不高,不信可以跑个f(100,100)试试。能不能有别的方法呢?答案是肯定的——动态规划。

动态规划是一种自底向上的算法,而递归是自顶向下的。递归的时候总是要将原问题分解成子问题,子问题中的变量等信息存在堆栈中,如果它要求的下一个问题中包含了我们已经求解出的子问题,递归算法会存在一个重复计算子问题的情况;

而动态规划则是基于已经求好的子问题去逐步逐步求解顶层问题,而且调用子问题是在常数时间复杂度内完成的。其实问题分解的思路,递归和动态规划是完全一样的,个人认为只是人为地运用一些办法,提高问题求解的速度。

### 动态规划代码

“`c++

// 简单整数划分问题,动态规划算法

int DP_f(int n)

{

int a[MAX_SIZE + 1][MAX_SIZE + 1] = { 0 };  // a中存放的是f(row,col)

// 所有f(r,1)=1

for (int i = 1;i <= n;i++)

{

a[i][1] = 1;

}

// 所有f(1,c)=1

for (int j = 1;j <= n;j++)

{

a[1][j] = 1;

}

// 自底向上求解

for (int i = 2;i <= n;i++)

{

for (int j = 2;j <= n;j++)

{

if (i == j)

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

else if (i < j)

a[i][j] = a[i][i];

else

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

}

}

return a[n][n];

}

“`

先讲到这里,来只柴犬放松一下吧。

<img src=”https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1523794723672&di=9c6249afcef0420554cca4587d2eba50&imgtype=0&src=http%3A%2F%2Fwx3.sinaimg.cn%2Flarge%2Fc0788b86gy1fi1y8f20jzj20qo0zk124.jpg” width=”35%” height=”35%” />

    原文作者:动态规划
    原文地址: https://blog.csdn.net/qq_37174526/article/details/79951287
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞