Ignatius and the Princess III - 拆分数-动态规划(dp)
---恢复内容开始---
2017-08-10 20:00:45
writer:pprp
拆分数:
把正整数n拆分成k个正整数之和的方案数;
问题转换:将1转化为2
1、把n表示成m个正整数之和的方案数
2、把n表示成不超过m的正整数之和的方案数
两者答案相同:解释Ferrers图
用dp来做,dp[i][j]的意思是 i 表示成 不超过 j 的方案数
边界条件:
dp[0][j] = 1 , dp[[i][1] = 1 , dp[1][j] = 1;
状态转移:
dp[i][j] = dp[i][j-1]+dp[i-j][j];
n个数划分成不超过m的整数的方案,若最大数为m,那么把最大数去掉,等价于把n-m分成不超过m的整数的方案,
若最大数不是m,那么等价于把n分成不超过m-1的方案数
代码如下:
#include <iostream> #include <cstring> #include <cmath> #include <cstdio> using namespace std; const int maxn = 130; int dp[maxn][maxn]; void DP() { for(int i = 1; i < maxn ; i++) { dp[i][1] = dp[1][i] = dp[0][i] = 1; } for(int i = 2 ; i < maxn ; i++) { for(int j = 2 ; j < maxn ; j++) { if(i >= j) dp[i][j] = dp[i][j-1]+dp[i-j][j]; else dp[i][j] = dp[i][i]; } } } int main() { int n; memset(dp,0,sizeof(dp)); DP(); while(cin >> n) { cout << dp[n][n] << endl; } return 0; }
代码改变世界