您的位置:首页 > 其它

划分型动态规划 之 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;
}





                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: