ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

数的划分

2022-01-13 22:35:08  阅读:168  来源: 互联网

标签:简洁 分法 整数 划分 为空 dp 式子


题目描述

将整数 n 分成 k 份,且每份不能为空,问有多少种不同的分法。当 n=7, k=3n=7,k=3 时,下面三种分法被认为是相同的:1,1,5; 1,5,1; 5,1,1

输入格式

一行两个数 n , k。

输出格式

一行一个整数,即不同的分法数。

样例

输入数据 1

7 3

输出数据 1

4

四种分法为:1,1,5;1,2,4;1,3,3;2,2,3。

数据范围与提示

6≤n≤200, 2≤k≤6。

 

题解:

定义一个数组dp[][],dp[i][j]表示将整数 i 划分为 j 份 的方案数。dp[i][j]的动态转移方程为 :

 

那么我们应该如何理解该式子呢?首先,如果拿到一个整数 i ,因为题目中要求每份不能为空,因此必须先拿出 j 个数位将 j 份分别放上1,此时剩下 i - j个数。那么剩下的数如何处理呢?可以将其全部分到一份当中(dp[i-j][1]),也可以分到两份中(dp[i-j][2]),...,也可以分到 j 份中(dp[i-j][j]),而每一种分法都是不相同的,所以可以将其全部加起来,和即为dp[i][j]。

不过这个式子看起来并不简洁,为了求得一个简洁的式子,我们再求一个dp[i-1][j-1],

 

比较上面两个式子可得,

 

这就是一个比较简洁的递推式子了,有点类似于高中数学中的裂项相消原理。

这里注意 i , j 的取值范围,i = 1~n,j = 1~ k,但是求dp[i][j]时,必须保证 i>=j(划分的份数不能超过给定的整数)。

```

//
// Created by 23011 on 13/1/2022.
//
#include<stdio.h>
#include<string.h>
int a[200][8];
int main()
{
int n, k, i, j;
scanf("%d %d", &n, &k);
a[0][0] = 1;
for(i = 1; i <= n; ++i)
{
for(j = 1; j <= k; ++j)
{
if(j > i)
a[i][j] = 0;
else
a[i][j] = a[i - 1][j - 1] + a[i - j][j];
}
}
printf("%d\n", a[n][k]);
return 0;
}

标签:简洁,分法,整数,划分,为空,dp,式子
来源: https://www.cnblogs.com/cherish-cv/p/15799926.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有