• 数分解问题:把一个数分解成很多数


    数分解问题:把一个数分解成很多数

     

    1.数字相同但位置不同的方案看作两个方法:

    5=1+1+2+3=2+3+1+1看作是不同的两个方法

    f(n)= f(n-1)+f(n-2)+…+ f(1) +1       (第一个数字为1,2,…,n-1,n)

     

    证明 f(n)=2^(n-1):

    n=1,f(1)=1=2^(1-1),

    假设n<=k时,f(n)=2^(n-1),

    f(k+1)=1+1+2+…+2^(k-1)=2^k,得证。

     

    Code:

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #define maxn 1000
     4 
     5 long arr[maxn+1],pos=0,num=0;
     6 
     7 void dfs(long d)
     8 {
     9     long i;
    10     for (i=1;i<d;i++)
    11     {
    12         pos++;
    13         arr[pos]=i;
    14         dfs(d-i);
    15         pos--;
    16     }
    17     num++;
    18     printf("%ld : ",num);
    19     //last element is d
    20     for (i=1;i<=pos;i++)
    21         printf("%ld ",arr[i]);
    22     printf("%ld
    ",d);
    23 }
    24 
    25 int main()
    26 {
    27     long n;
    28     scanf("%ld",&n);
    29 dfs(n);
    30     printf("ans = %ld
    ",num);
    31     return 0;
    32 }

     

    Result:

    2. 数字相同但位置不同的方案看作一个方法

    5=1+1+2+3=2+3+1+1看作是同一个方法

     

    程序做法:按从小到大(可以相同)排序,这样就保证不重复

    4=1+1+1+1 (1<=1<=1<=1) =1+1+2 (1<=1<=2) =1+3 (1<3) =4

    t(n,k):对数字n分解,最大的数为k的方法数

    I.(n<>k)

    t(n,k)=t(n-k,1)+t(n-k,2)+t(n-k,3)+……+t(n-k,s)

    (s满足s<=k且s<= n-k)

    II.(n=k)

    t(n,k)=1

     

    f(n)=t(n,n)+t(n,n-1)+t(n,n-2)+t(n,1)

    Code:

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #define maxn 1000
     4 
     5 long arr[maxn+1],pos=0,num=0;
     6 
     7 void dfs(long d)
     8 {
     9     long i;
    10     //arr[pos+1](i)>=arr[pos]
    11     //所以要初始化arr[0]=1
    12     for (i=arr[pos];i<d;i++)
    13     {
    14         pos++;
    15         arr[pos]=i;
    16         dfs(d-i);
    17         pos--;
    18     }
    19     if (d>=arr[pos])
    20     {
    21         num++;
    22         printf("%ld : ",num);
    23         //last element is d
    24         for (i=1;i<=pos;i++)
    25             printf("%ld ",arr[i]);
    26         printf("%ld
    ",d);
    27     }
    28 }
    29 
    30 int main()
    31 {
    32     long n;
    33     scanf("%ld",&n);
    34     arr[0]=1;
    35     dfs(n);
    36     printf("ans = %ld
    ",num);
    37     return 0;
    38 }

    Result:

    求方法总数:

    Code:

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #define maxn 1000
     4 
     5 long t[maxn+1][maxn+1],f[maxn];
     6 
     7 long min(long a,long b)
     8 {
     9     if (a>b)
    10         return b;
    11     else
    12         return a;
    13 }
    14 
    15 int main()
    16 {
    17     long n,i,j,k;
    18     scanf("%ld",&n);
    19     for (i=1;i<=n;i++)
    20     {
    21         t[i][i]=1;
    22         for (j=1;j<=i-1;j++)
    23             t[i][j]=0;
    24         f[i]=0;
    25     }
    26     //t(n,k)=t(n-k,1)+t(n-k,2)+t(n-k,3)+……+t(n-k,s)
    27     for (i=2;i<=n;i++)
    28         for (k=1;k<i;k++)
    29             //t(i,k)
    30             for (j=1;j<=min(k,i-k);j++)
    31                 t[i][k]+=t[i-k][j];
    32     for (i=1;i<=n;i++)
    33         for (j=i;j>=1;j--)
    34             f[i]+=t[i][j];
    35     for (i=1;i<=n;i++)
    36         printf("%ld : %ld
    ",i,f[i]);
    37     return 0;
    38 }

     

    Situation:

    n       =1,2,3,4,5,6 , 7 , 8 , 9 , 10

    Total         =1,2,3,5,7,11,15,22,30,42

     

     

     

    3.数字不允许重复

    如不可以5=3+1+1 (不能有两个1)

     

     

    程序做法:按从小到大(不可以相同)排序,这样就保证不重复

    6=1+2+3 (1<2<3) =1+5 (1<5) =2+4 (2<4) =6

    t(n,k):对数字n分解,最大的数为k的方法数

    I.(n<>k)

    t(n,k)=t(n-k,1)+t(n-k,2)+t(n-k,3)+……+t(n-k,s)

    (s满足s<k且s<= n-k)

    II.(n=k)

    t(n,k)=1

     

    f(n)=t(n,n)+t(n,n-1)+t(n,n-2)+t(n,1)

     

    Code:

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #define maxn 1000
     4 
     5 long arr[maxn+1],pos=0,num=0;
     6 
     7 void dfs(long d)
     8 {
     9     long i;
    10     //arr[pos+1](i)>arr[pos]
    11     //所以要初始化arr[0]=0
    12     //与程序2(i=arr[pos])不同
    13     for (i=arr[pos]+1;i<d;i++)
    14     {
    15         pos++;
    16         arr[pos]=i;
    17         dfs(d-i);
    18         pos--;
    19     }
    20     //与程序2(d>=arr[pos])不同
    21     if (d>arr[pos])
    22     {
    23         num++;
    24         printf("%ld : ",num);
    25         //last element is d
    26         for (i=1;i<=pos;i++)
    27             printf("%ld ",arr[i]);
    28         printf("%ld
    ",d);
    29     }
    30 }
    31 
    32 int main()
    33 {
    34     long n;
    35     scanf("%ld",&n);
    36     arr[0]=0;
    37     dfs(n);
    38     printf("ans = %ld
    ",num);
    39     return 0;
    40 }

    Result:

    求方法总数:

    Code:

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #define maxn 1000
     4 
     5 long t[maxn+1][maxn+1],f[maxn];
     6 
     7 long min(long a,long b)
     8 {
     9     if (a>b)
    10         return b;
    11     else
    12         return a;
    13 }
    14 
    15 int main()
    16 {
    17     long n,i,j,k;
    18     scanf("%ld",&n);
    19     for (i=1;i<=n;i++)
    20     {
    21         t[i][i]=1;
    22         for (j=1;j<=i-1;j++)
    23             t[i][j]=0;
    24         f[i]=0;
    25     }
    26     //t(n,k)=t(n-k,1)+t(n-k,2)+t(n-k,3)+……+t(n-k,s)
    27     for (i=2;i<=n;i++)
    28         for (k=1;k<i;k++)
    29             //t(i,k)
    30             //与程序2(j<=min(k,i-k))不同的地方
    31             for (j=1;j<=min(k-1,i-k);j++)
    32                 t[i][k]+=t[i-k][j];
    33     for (i=1;i<=n;i++)
    34         for (j=i;j>=1;j--)
    35             f[i]+=t[i][j];
    36     for (i=1;i<=n;i++)
    37         printf("%ld : %ld
    ",i,f[i]);
    38     return 0;
    39 }

     

    Situation:

    n       =1,2,3,4,5,6,7,8,9,10

    Total         =1,1,2,2,3,4,5,6,8,10

  • 相关阅读:
    JDK源码分析 – HashMap
    牛哄哄的celery
    redis数据库基础篇
    RPC的入门应用
    Python的常用模块
    消息队列之真知灼见
    面向对象编程(2)
    python3的C3算法
    面向对象编程(1)
    CRM项目之stark组件(2)
  • 原文地址:https://www.cnblogs.com/cmyg/p/6720469.html
Copyright © 2020-2023  润新知