问题描述 :

  有 n 个无区别的物品 , 将他们分成 不超过 m 堆, 问有多少种分法 ?  

例如 :

  n = 4 , m = 3 , 则总共有的分法是 1 + 2 +1 , 0 + 1 + 3 , 0 + 2 + 2 , 0 + 0 +  4 。

  共有 4 种分法 ,观察这四种分法 , 有一个特点 , 即 带 0 的划分 和不带 0 的划分 ,首先不带 0 的划分 , 比如 1 + 2 + 1 就可以视为是 0 + 1 + 0 的划分数递推加 1 得到的 , 带 0 的划分就可以视为是 将 n 分为 m - 1 份所得到的划分数 。

代码示例 :

int n, m;
int dp[100][100]; int main() {
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout); cin >> n >> m;
dp[0][0] = 1;
for(int i = 1; i <= m; i++) dp[0][i] = 1; for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
if (i >= j) dp[i][j] = dp[i-j][j]+dp[i][j-1];
else dp[i][j] = dp[i][j-1];
}
}
cout << dp[n][m] << endl;
return 0;
}

将数字 n 分成不超过 m 份的方案数

dp[i][j] 表示将数字 i 分成 j 份的方案数,转移的话分为两种,

第一种是 假设其中有某一堆的个数为 1 , 则可以有 dp[i-1][j-1] 推来

第二种是 假设其中所有堆的个数都大于等于 2, 则可以由 dp[i-j][j] 推来

int n, m;
int dp[205][100]; int main() {
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout); cin >> n >> m;
dp[0][0] = 1; for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
if (i >= j) dp[i][j] = dp[i-j][j]+dp[i-1][j-1];
}
}
cout << dp[n][m] << endl;
return 0;
}

最新文章

  1. DedeCMS flink_add Getshell漏洞 管理员CSRF漏洞
  2. 女生学Web前端优势往往很明显
  3. [原创]cocos2d-x研习录-第三阶 特性之瓦片地图集
  4. UC~移动端的IE!!!坑总结
  5. vim使用01
  6. Linux 编写c++程序之openssl
  7. JLINK固件,JLINK驱动和JLINK硬件版本之间的关系,以及固件升级方法
  8. Server对象的Execute方法
  9. poj 3295 Tautology (构造)
  10. NVMe 与 AHCI
  11. Js 命名空间注册方法
  12. nodejs 模拟form表单上传文件
  13. 1129: 零起点学算法36——3n+1问题
  14. 【BZOJ4403】序列统计(组合数学,卢卡斯定理)
  15. raid5两块硬盘离线怎么办? 强制上线失败如何恢复数据
  16. docker+efk+.net core部署
  17. getchar(),scanf(),gets(),cin,输入字符串
  18. Bitcoin源代码编译安装详解
  19. linux 系统监控和进程管理
  20. [HDU3726]Graph and Queries

热门文章

  1. python编程之进程
  2. 【js】React-Native 初始化时报错
  3. POJ 1236 Network of Schools(tarjan)
  4. 两种方法,轻松上手ConfigMap!
  5. 2018-2-13-win10-uwp-判断文件存在
  6. 【37.74%】【codeforces 725D】Contest Balloons
  7. 【u033】地震逃生
  8. C#面试题整理2(不带答案)
  9. E40笔记本无线网卡
  10. 30分钟全方位了解阿里云Elasticsearch(附公开课完整视频)