/*
Name:整数拆分 两种做法 (dp)
Actor:HT
Time:2015年9月28日
Error Reporte: 1.初始化边界处理 没弄清
*/
#include <iostream>
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <vector>
#include <algorithm>
using namespace std;
#define N 125
int dp[N][N];
void dd() {
for (int i = 1; i <= 120; i++)
{
dp[i][1] = dp[1][i] = dp[0][i] = 1;
}
for (int i = 2; i <= 120; i++)
{
for (int j = 2; j <= 120; j++)
{
if (i < j) dp[i][j] = dp[i][i];
else dp[i][j] = dp[i - j][j] + dp[i][j - 1];
}
}
}
int main()
{
int i, j;
int n, m;
while (scanf("%d %d", &n, &m) != EOF)
{
memset(dp, 0, sizeof(dp));
for (i = 1; i <= n; i++) //初始化边界很重要:
{
dp[0][i] = 1; //处理成功,n到0了,要算一种
}
for (i = 1; i <= n; i++)
{
for (j = 1; j <= m; j++)
{
if (i >= j)
dp[i][j] = dp[i - j][j] + dp[i][j - 1]; //bug点: dp[i-j][j] 而不是dp[i-j][j-1]
else if (i < j) //注意判断大小 此处
dp[i][j] = dp[i][i];
}
}
printf("%d\n", dp[n][m]);
}
return 0;
}
//d[n][m] = n的小于拆分 出现所有数字小于等于m
//d[n][m] = d[n-m][m] + d[n][m-1] 就两种情况,要么拿,要么不拿!!!!!!!!!!拿了的话,仍然要关于同一个m讨论:是否继续拿
/*Another Way*/
/*
#include <iostream>
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <vector>
#include <algorithm>
using namespace std;
#define N 20
int dp[N];
int main()
{
int i, j;
int n, m;
while (scanf("%d %d", &n, &m) != EOF)
{
memset(dp, 0, sizeof(dp));
dp[0] = 1;
for (j = 1; j <= n; j++)
{
for (i = 1; i <= n; i++)
{
if (i >= j)
dp[i] += dp[i - j];
}
}
printf("%d\n", dp[n]);
}
}
//dp[i] = 第i个数的拆分方法
//dp[i] = dp[i] + d[i-j] 其中j是本次要加的数
//大体思路:分别讨论要加的数(1,2,3,...),对于每个拆分的数i,既是i = (i-j) + j
// 那么就是d(i-j)的种数
*/
[动态规划]整数拆分(纯DP)
最新推荐文章于 2024-07-05 16:04:23 发布