划分型动态规划 之 CODE[VS] 1039 数的划分 2001年NOIP全国联赛提高组
2015-11-14 17:06
399 查看
/* dp[i][k] := 将整数i分成k份,分法种数 初始化: dp[][] = { 0 } dp[i][1] = 1 状态方程: dp[i][k] = dp[i-1][k-1] + dp[i-k][k] 思想:(引自byvoid大神的博客:https://www.byvoid.com/blog/noip-allsolutions#.E6.95.B0.E7.9A.84.E5.88.92.E5.88.86) 每种拆分方案中,最小的数为w,按照w的不同,我们可以把拆分方案分成2类: w=1,我们把1除去,则剩余部分正好是i-1拆分成k-1部分,一共有dp[i-1,k-1])个; w>1,所有的数都>1,我们把所有的数-1,则正好是i-k拆分成k部分,一共有dp[i-k,k]个。 根据加法原理,得出以上方程。 答案: dp [K] */
#define _CRTDBG_MAP_ALLOC #include <stdlib.h> #include <crtdbg.h> #define _CRT_SECURE_NO_WARNINGS #define HOME #include <iostream> #include <cstdlib> #include <cstdio> #include <cstddef> #include <iterator> #include <algorithm> #include <string> #include <locale> #include <cmath> #include <vector> #include <cstring> using namespace std; const int INF = 0x3f3f3f3f; const int MaxN = 210; const int MaxK = 10; int N, K; string numStr; int dp[MaxN][MaxK] = { 0 }; void Solve() { for (int i = 1; i <= N; ++i) { // 划分从2开始,因为dp[][1]已经初始化过了,否则值会被0覆盖掉。 for (int j = 2; j <= K; ++j) { if (i < j) break; dp[i][j] = dp[i - 1][j - 1] + dp[i - j][j]; } } cout << dp [K] << endl; } int main() { #ifdef HOME freopen("in", "r", stdin); //freopen("out", "w", stdout); #endif cin >> N >> K; for (int i = 1; i <= N; ++i) { dp[i][1] = 1; } Solve(); #ifdef HOME cerr << "Time elapsed: " << clock() / CLOCKS_PER_SEC << " ms" << endl; _CrtDumpMemoryLeaks(); system("pause"); #endif return 0; }
相关文章推荐
- 总结iOS 多线程学习过程四
- Linux下自定义字符串数组作为文件名,创建文件
- Spark修炼之道(基础篇)——Linux大数据开发基础:第十节:Shell编程入门(二)
- 安卓实现简单的发送短信功能
- java基础一
- 旭说数据结构之散列表(哈希表)
- C语言的那些秘密之---函数返回局部变量
- sicily 1145. 校门外的树
- 叉积在ACM中的应用
- poj 2718
- 第二天-计算机硬件基本知识和linux发展简史
- Spark修炼之道(基础篇)——Linux大数据开发基础:第九节:Shell编程入门(一)
- 线程间通讯-------解决安全问题
- 黑盒测试和白盒测试区别
- android 定位的4种方式介绍
- 采购
- ubuntu14.04 有道辞典 安装成功后 打不开 的 解决办法
- C#之串口的一些问题
- iOS9开放的新API--Spotlight使用指南
- PHP:修改phpstorm的字体样式和大小