zoukankan      html  css  js  c++  java
  • hdu 4651 Partition(整数拆分+五边形数)

     

    Partition

    Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 462    Accepted Submission(s): 262

    Problem Description

     

    How many ways can the numbers 1 to 15 be added together to make 15? The technical term for what you are asking is the "number of partition" which is often called P(n). A partition of n is a collection of positive integers (not necessarily distinct) whose sum equals n.
    Now, I will give you a number n, and please tell me P(n) mod 1000000007.

     

     


    Input

     

    The first line contains a number T(1 ≤ T ≤ 100), which is the number of the case number. The next T lines, each line contains a number n(1 ≤ n ≤ 105) you need to consider.

     

     


    Output

     

    For each n, output P(n) in a single line.

     

     


    Sample Input

     

    4 5 11 15 19

     

     


    Sample Output

     

    7 56 176 490

     

     


    Source

     

     

     


    Recommend

     

    zhuyuanchen520

     

     

     

     

     

     

     

    欧拉函数的倒数是分割函数母函数,亦即:

    p(n)生成函数

    sum_{n=0}^infty p(n)x^n = prod_{k=1}^infty left(frac {1}{1-x^k} 
ight)   (1)

    利用五边形数定理可得到以下的展开式:

    prod_{k=1}^infty (1-x^k)=sum_{i=-infty}^infty(-1)^ix^{i(3i-1)/2}. (2)
    将(2)式带入(1)式,并乘到(1)式的左边,进行展开,合并同类项,根据非常数项的系数为0!!
     
    即将p(n)生成函数配合五边形数定理,可以得到以下的递归关系式
    p(n) = sum_i (-1)^{i-1} p(n-q_i)

     

     

     

     1 #include<stdio.h>
     2 typedef long long ll;
     3 const int mo=1000000007;
     4 ll p[100010];
     5 void pre()//打表,欧拉函数的倒数是分割函数的母函数!!! 
     6 {
     7     p[0]=1;
     8     for(ll i=1;i<=100000;i++)
     9     {
    10         ll t=1,ans=0,kk=1;
    11         while(1)
    12         {
    13             ll tmp1,tmp2;
    14             tmp1=(3*kk*kk-kk)/2;
    15             tmp2=(3*kk*kk+kk)/2;
    16             if(tmp1>i)break;
    17             ans=(ans+t*p[i-tmp1]+mo)%mo;
    18             if(tmp2>i)break;
    19             ans=(ans+t*p[i-tmp2]+mo)%mo;
    20             t=-t;
    21             kk++;
    22         }
    23         p[i]=ans;
    24     }
    25 }
    26 int main()
    27 {
    28     pre();
    29     int T,n;
    30     scanf("%d",&T);
    31     while(T--)
    32     {
    33         scanf("%d",&n);
    34         printf("%lld
    ",p[n]);
    35     }
    36 }
    View Code

     

     

  • 相关阅读:
    LeetCode: Reverse Words in a String && Rotate Array
    LeetCode: Maximum Product Subarray && Maximum Subarray &子序列相关
    =new、=null、.clear()、system.gc()的区别
    对象转字符串的效率问题
    Java遍历Map对象的四种方式
    JDK升级
    eclipse的任务列表
    统一修改数据库表名字段大小写
    get传数组
    vue编辑回显问题
  • 原文地址:https://www.cnblogs.com/skykill/p/3244982.html
Copyright © 2011-2022 走看看