自然数的拆分(多种方法)

链接网址:http://tyvj.cn/Problem_Show.asp?id=1171

 
自然数拆分
 
     
   
  描述  
  输入自然数n,然后将其拆分成由若干数相加的形式,参与加法运算的数可以重复。
     
     
  输入格式 Input Format  
  输入只有一个整数n,表示待拆分的自然数n。 n<=80
     
     
  输出格式 Output Format  
  输出一个数,即所有方案数
     
     
  样例输入  
  7
     
     
  样例输出  
  14
     
     
  时间限制 Time Limitation  
  各个测试点1s
     
     
  注释  
  解释:
输入7,则7拆分的结果是
7=1+6
7=1+1+5
7=1+1+1+4
7=1+1+1+1+3
7=1+1+1+1+1+2
7=1+1+1+1+1+1+1
7=1+1+1+2+2
7=1+1+2+3
7=1+2+4
7=1+2+2+2
7=1+3+3
7=2+5
7=2+2+3
7=3+4


一共有14种情况,所以输出14

 

记忆式搜索

 

//  将n拆成不超过k的多个数的和
//  f(n,k)=f(n-k,k-1)+f(n,k-1)
// 记忆式搜索
#include 
#include 
using namespace std;
int a[81][81];
int f(int n,int k)
{
    if (a[n][k]!=-1) return a[n][k];//还没有算的 
    if ( n==0 ) return a[n][k]=1;//
    if ( k==0 ) return a[n][k]=0;//
    if ( n>n;
    cout<


 

动态规划

#include 
#include 
using namespace std;
int dp[81][81];
int main(int argc, char *argv[])
{
    int i,k,n,s;
    while(cin>>n){ 
        memset(dp,0,sizeof(dp));
        dp[0][0]=1;//dp[1][1]=dp[0][0]+dp[0][1]只能是dp[0][0]为1 
        for (i=1; i<=n; i++)// dp[i][k] i划分为k个数 
            for (k=1; k<=i; k++)
                dp[i][k]=dp[i-1][k-1]+dp[i-k][k];
        for (s=0,k=1; k<=n; k++)
            s=s+dp[n][k];
        cout<


母函数解法

#include
#include
#include
using namespace std;
const int N=10000;
int n,a[N],b[N],elem[1005];

void fun(int n)
{
    int i,j,k;
    memset(a,0,sizeof(a));
    memset(b,0,sizeof(b));
    for(i=0;i<=n;i++) a[i]=1; //先生成一个函数,实质为1+x+x^2+x^3+……x^n
    for(i=2;i<=n;i++){       //生成其余的函数对应1+x^i+x^2i+……
        for(j=0;j<=n;j++)
            for(k=0;k+j<=n;k+=i)
                b[j+k]+=a[j];
            //二多项式相乘,先将第一个多项式逐项乘后一个多项式,
            //如果二项相乘积大于x^n便可结束,道理如上一样,对最后结果无影响,
            //为什么使用k+=i*i,其实质就是一个生成函数:1+x^(i*i)+x^2(i*i)+……,
            //没有的项系数为0,对于有效的项刚累加a[j],
            //不是加1的原因为可能a[]中不存在第j项,也就是说x^j的系数为0
            for(k=0;k<=n;k++)//将结果保存在a[]中,将b[]清0,以便再循环使用
            {   a[k]=b[k];b[k]=0;}
    }        
} 

int main()
{
    scanf("%d",&n);{
        fun(n);
        int t=(a[n]-1)%2147483648;
        printf("%d\n",t);
    }
    return 0;
    
}


 

你可能感兴趣的:(搜索)