题目描述:给你一个整数n,比如是4,输出可以将4划分的总数目。
可以划分为
4
3 1
2 2 2 1 1
1 1 1 1
这样总共有五种情况。
书上写的是递归实现的方法,很耗费时间,输入100之后还需要5s+的样子才能运行出来。
可以直接使用动态规划。 a[n][m]表示总和为n,其中最大的数字是m的总类数。我们所需要求得答案便是a[n][n].
(1)a[n][n]=a[n][n-1]+1
(2)a[n][m]=a[n][m-1]+a[n-m][m] (m<n&&n-m>=m) n-m是因为要使得这一行最大数字必须为m
(3)a[n][m]=a[n][m-1]+a[n-m][n-m] (m<n&&n-m<m)
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
long long a[1002][1002];
int fun(int n,int m) //递归实现太耗费时间
{
if(n<1||m<1) return 0;
else if(n==1||m==1) return 1;
else if(n<m) return fun(n,n);
else if(n==m) return 1+fun(n,n-1);
else return fun(n,m-1)+fun(n-m,m);
}
int main()
{
int n,i,j;
memset(a,0,sizeof(a));
for(i=1;i<=1000;i++)
a[i][1]=a[1][i]=1;
for(i=2;i<=1000;i++)
{
for(j=2;j<i;j++)
{
if(i-j>=j) a[i][j]=a[i][j-1]+a[i-j][j];
else a[i][j]=a[i][j-1]+a[i-j][i-j];
}
a[i][i]=a[i][i-1]+1;
}
while(cin>>n)
{
//cout<<fun(n,n)<<endl;
cout<<a[n][n]<<endl;
}
return 0;
}