题目描述:给你一个整数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; }