动态规划思想-划分数问题

Description:

给定一个数,给定一个特定的数量,要求将这个数划分为特定个数量的部分。

请问:共有多少种划分情况?

Input:

数num,规定划分数量part

Output:
划分总数

Sample Input:

4 3

Sample Output:

4(1+1+2,2+2,1+3,4) 

要求:
划分出来的数不能为零,划分数量不能为零。并且,仅顺序不同的划分算作一种划分。

例如:

1+3和3+1算是同一种划分。

思路:

对于这个问题,我们考虑如何使用动态规划递推来做。

首先dp[i][j]代表的是将j划分i,i-1,i-2...1份所对应的总共的划分数量。这里总共对应三种情况:

对于i==j的情况,那么将j正好划分为i份就只对应一种情况也就是全一。剩下的就只要再加上将j划分为i-1,i-2...1份的情况就可以了。也就是:

dp[i][j]=1+dp[i-1][j]。

对于i<j的情况,那么考虑将j正好划分为i份,由于j比i大,所以i份的划分中,每一个划分至少是一,所以我们一定有一个基础划分也就是1,1,1,1,1...1。再将剩余的数字j-i分配到这i个”份“上,我们就得到了将j正好划分为i份的结果。剩下的就只要再加上将j划分为i-1,i-2...1份的情况就可以了。也就是:

dp[i][j]=dp[i-1][j]+dp[i][j-i]。

对于i>j的情况,将j强行分为i份是不可能的,至少i==j时才有得分。所以这种情况其实是等价于第一种情况的。也就是:

dp[i][j]=dp[i-1][j]。

Code:

#include<iostream>
using namespace std;

long long dp[10001][10001];

int num;
int part;
//int M;

void solution() {
    dp[0][0] = 1;
    for (int i = 1;i <= part;i++) {
        for (int j = 0;j <= num;j++) {
            if (j > i)
                dp[i][j] = dp[i - 1][j] + dp[i][j - i];
            else if (j == i)
                dp[i][j] = dp[i - 1][j] + 1;
            else 
                dp[i][j] = dp[i - 1][j];
        }
    }

    cout << dp[part][num];
}

int main() {
    cin >> num >> part;
    solution();
    return 0;
}

 

  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
动态规划 目录 概念引入 例1:最短路问题 最优化原理 根据最优化原理求解最短路问题 动态规划适应于解决什么样的问题 例2:背包问题 例3:马尔可夫过程问题 例4:迷宫镜子问题 例5:防卫导弹问题 例6:剩余糖果问题 动态规划的基本概念 动态规划的基本思想 动态规划的实质是分治思想和解决冗余,因此,动态规划是一种将问题实例分解为更小的、相似的子问题,并存储子问题的解而避免计算重复的子问题,以解决最优化问题算法策略。 动态规划的适用条件 1.最优化原理 若由点A到点E的最短路线过某点P,则在这条路线上P到E的距离是P、E两点间各条路线中的最短距离。最优化原理也可这样阐述:一个最优化策略具有这样的性质,不论过去状态和决策如何,对前面的决策所形成的状态而言,余下的诸决策必须构成最优策略。 2.无后效性 所谓无后效性是指:过去的决策只能通过当前的状态影响未来的发展,当前的状态是以往状态的总结。也可这样阐述:在状态转移过程中,一旦到达某阶段某一状态,则以后过程的发展仅与这一状态有关,而与此状态之前的决策无关。 动态规划法所针对的问题有一个显著的特征 即它所对应的子问题树中的子问题呈现大量的重复。动态规划法的关键就在于,对于重复出现的子问题,只在第一次遇到时加以求解,并把答案保存起来,让以后再遇到时直接引用,不必重新求解。 动态规划的逆向思维法是指从问题目标状态出发倒退回初始状态或边界状态的思维方式,其要点可归纳为以下三个步骤:(1)分析最优值的结构,刻画其结构特征;(2)递归的定义最优值;(3)按自底向上或自顶向下记忆化的方式计算最优值。 例7:计算矩阵连乘积 问题描述 在科学计算中经常要计算矩阵的乘积。矩阵A和B可乘的条件是矩阵A的列等于矩阵B的行。若A是一个p×q的矩阵,B是一个q×r的矩阵,则其乘积C=AB是一个p×r的矩阵。其标准计算公式为: 最长公共子序列问题LCS 一个给定序列的子序列是在该序列中删去若干元素后得到的序列。确切地说,若给定序列X=,则另一序列Z=是X的子序列是指存在一个严格递增的下标序列 ,使得对于所有j=1,2,…,k有 最长公共子序列问题LCS 最长公共子序列(LCS)问题:给定两个序列X=和Y=,要求找出X和Y的一个最长公共子序列 动态规划算法可有效地解此问题。下面我们按照动态规划算法设计的各个步骤来设计一个解此问题的有效算法。 1.最长公共子序列的结构 解最长公共子序列问题时最容易想到的算法是穷举搜索法,即对X的每一个子序列,检查它是否也是Y的子序列,从而确定它是否为X和Y的公共子序列,并且在检查过程中选出最长的公共子序列。X的所有子序列都检查过后即可求出X和Y的最长公共子序列。X的一个子序列相应于下标序列{1, 2, …, m}的一个子序列,因此,X共有2m个不同子序列,从而穷举搜索法需要指时间。 事实上,最长公共子序列问题也有最优子结构性质,因为我们有如下定理: 定理: LCS的最优子结构性质 设序列X=和Y=的一个最长公共子序列Z=,则: 若xm=yn,则zk=xm=yn且Zk-1是Xm-1和Yn-1的最长公共子序列; 若xm≠yn且zk≠xm ,则Z是Xm-1和Y的最长公共子序列; 若xm≠yn且zk≠yn ,则Z是X和Yn-1的最长公共子序列。 其中Xm-1=,Yn-1=,Zk-1=。 2.子问题的递归结构 由最长公共子序列问题的最优子结构性质可知,要找出X=和Y=的最长公共子序列,可按以下方式递归地进行:当xm=yn时,找出Xm-1和Yn-1的最长公共子序列,然后在其尾部加上xm(=yn)即可得X和Y的一个最长公共子序列。当xm≠yn时,必须解两个子问题,即找出Xm-1和Y的一个最长公共子序列及X和Yn-1的一个最长公共子序列。这两个公共子序列中较长者即为X和Y的一个最长公共子序列。 由此递归结构容易看到最长公共子序列问题具有子问题重叠性质。例如,在计算X和Y的最长公共子序列时,可能要计算出X和Yn-1及Xm-1和Y的最长公共子序列。而这两个子问题都包含一个公共子问题,即计算Xm-1和Yn-1的最长公共子序列。 (1)初始化操作,c[i,0]=0,i=1,2,…,m;c[0,j]=0,j=1,2

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值