• 数学:整数拆分


    使用五边形数定理进行整数拆分

    先介绍一个叫做分拆数的概念:

    将一个数用一个或多个正整数的无序和来表示

    例如4的分拆有5种:4 , 3+1 , 2+2 , 2+1+1 , 1+1+1+1

    还有一个概念叫做限制分拆,就是给分拆加上限制条件,下面给出一些常见的结论

    n的分拆数中最大部分为m的个数=把n分拆成m部分的个数
    
    n的分拆数中每一部分都小于等于m的个数=把n分成m份或更小
    
    的分拆数中每部分的数都相等的个数=n 的因子个数
    Eg. 6=2+2+2, 6=3+3,6=1+1+1+1+1+1
    
    的分拆数中每部分都是1或2(或者把n分拆成1或2部分)的个数=floor(n/2+1);
    Eg. 6=1+1+1+1+1+1, 6=1+1+1+1+2, 6=1+1+2+2, 6=2+2+2
    floor()是向下取整
    
    n的分拆数中每部分都是1或2或3(或者把n分拆成1或2或3部分)的个数=(n+3)^2/12;

    然后是要点总结部分,转自https://blog.csdn.net/whai362/article/details/42530243

    至于问题的变式,等介绍完母函数(生成函数)之后再进行介绍

    HDU4651

     1 #include<cstdio>
     2 using namespace std;
     3 const int MOD=1e9+7;
     4 int n;
     5 int dp[100005];
     6 void init()
     7 {
     8     dp[0]=1;
     9     for(int i=1;i<=100000;i++)
    10     {
    11         for(int j=1,r=1;i-(3*j*j-j)/2>=0;j++,r*=-1)
    12         {
    13             dp[i]+=dp[i-(3*j*j-j)/2]*r;
    14             dp[i]%=MOD;
    15             dp[i]=(dp[i]+MOD)%MOD;
    16             if(i-(3*j*j+j)/2>=0)
    17             {
    18                 dp[i]+=dp[i-(3*j*j+j)/2]*r;
    19                 dp[i]%=MOD;
    20                 dp[i]=(dp[i]+MOD)%MOD;
    21             }
    22         }
    23     }
    24 }
    25 int main()
    26 {
    27     init();
    28     int T;
    29     scanf("%d",&T);
    30     while(T--)
    31     {
    32         scanf("%d",&n);
    33         printf("%d
    ",dp[n]);    
    34     }
    35     return 0;
    36 }
  • 相关阅读:
    C语言和指针-回顾02-const
    Linux内核学习-使用exec创建socket
    Archlinux安装和配置
    apt-get install failed
    Insmod module : operation not permitted
    5.2.5.用开发板来调试模块
    5.2.4.最简单的模块源码分析3
    5.2.3.最简单的模块源码分析2
    5.2.1.开启驱动开发之路
    总线,设备,驱动的关系
  • 原文地址:https://www.cnblogs.com/aininot260/p/9491796.html
Copyright © 2020-2023  润新知