数的划分
2022/1/13 23:09:00
本文主要是介绍数的划分,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
题目描述
将整数 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; }
这篇关于数的划分的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2025-01-11有哪些好用的家政团队管理工具?
- 2025-01-11营销人必看的GTM五个指标
- 2025-01-11办公软件在直播电商前期筹划中的应用与推荐
- 2025-01-11提升组织效率:上级管理者如何优化跨部门任务分配
- 2025-01-11酒店精细化运营背后的协同工具支持
- 2025-01-11跨境电商选品全攻略:工具使用、市场数据与选品策略
- 2025-01-11数据驱动酒店管理:在线工具的核心价值解析
- 2025-01-11cursor试用出现:Too many free trial accounts used on this machine 的解决方法
- 2025-01-11百万架构师第十四课:源码分析:Spring 源码分析:深入分析IOC那些鲜为人知的细节|JavaGuide
- 2025-01-11不得不了解的高效AI办公工具API