hdu-4615 Partition

来源:互联网 发布:绘制平面图的软件 编辑:程序博客网 时间:2024/05/21 10:41

题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=4651

题目大意就是整数拆分

数据特别大,不能用以前的递归

所以。。。  不能百度  只能谷歌抓狂http://en.wikipedia.org/wiki/Partition_%28number_theory%29

然后在里面找一个公式

Leonhard Euler'spentagonal number theorem implies the identity

p(n)=p(n-1)+p(n-2)-p(n-5)-p(n-7)+\cdots

p(n)=\sum_k (-1)^{k-1}p\left(n- k(3k -1)/2\right)

where the summation is over all nonzero integers k (positive and negative) andp(m) is taken to be 0 if m < 0.

但这个公式不完全,然后自己推理,再加小小的DP,就有代码了,

代码如下:

#include <iostream>#include <cstdio>#define MAX 100000+10#define MOD 1000000007using namespace std;int  f[MAX];void init(){    for(int i=3; i<=100000; i++)    {        f[i]=0;        for(int j=1; j*(3*j-1)/2 <=i; j++)        {            if(j%2==0)            {                f[i]=(f[i]-f[i-j*(3*j-1)/2]+MOD)%MOD;                if((i-j*(3*j-1)/2-j)>=0)                    f[i]=(f[i]-f[i-j*(3*j-1)/2-j]+MOD)%MOD;            }            else            {                f[i]= (f[i]+f[i-j*(3*j-1)/2])%MOD;                if((i-j*(3*j-1)/2-j)>=0)                    f[i]=(f[i]+f[i-j*(3*j-1)/2-j])%MOD;            }        }    }}int main(){    int T;    f[0]=1;f[1]=1;f[2]=2;    init();    scanf("%d",&T);    while(T--)    {        int n;        scanf("%d",&n);        printf("%d\n",f[n]);    }}


原创粉丝点击