Problem: 数字的拆分之二

Problem: 数字的拆分之二

Time Limit: 10 Sec Memory Limit: 128 MB

Description

将数字N进行拆分.使用的数字可以重复使用.

Input

每一行给出一个数字N,3<=N<=500.整个测试以0代表结束.

Output

拆分的种数.

Sample Input

3
0

Sample Output

3

HINT

i,j的含义就是:将整数i划分为j份的方案数。如果DP中要用到对前面状态求和,那么要么可以O(n^2)预处理sum[i][j],就可以简化DP方程,方程可简化为:f[i][j] = f[i-1][j-1] + f[i-j][j]。
DP函数:

for(i = 1; i <= n; i++)
for(j = 1; j <= (i > m ? m : i);j++)
f[i][j] = f[i-1][j-1] + f[i-j][j];
return f[n][m];

时间复杂度为O(min(n^2, nm))
Code:

#include<stdio.h>
long long n,m,dp[501][501]= {1},i,j,sum,con;
int main() {
	while(scanf("%lld",&n),n) {
		for(m=1; m<=n; sum+=dp[n][m++])//枚举拆分个数
			for(i=1; i<=n; i++)
				for(con=(i>m?m:i),j=1; j<=con; j++)
					dp[i][j]=dp[i-1][j-1]+dp[i-j][j];
		printf("%lld
",sum);
	}
}
原文地址:https://www.cnblogs.com/ZhaoChongyan/p/11740407.html