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);
}
}