HDU4651|HDU1028 Partition 整数拆分公式法
来源:互联网 发布:淘宝会员卡封面设置 编辑:程序博客网 时间:2024/06/01 10:39
题目链接:HDU4651
题目大意:给你n,求出n的拆分数,例如p(4)=5 4=1+1+1+1 ,4=1+1+2 , 4=1+3, 4=2+2,4=4;五种拆分,无序。
知识点:
1、广义五边形数:广义五边形数
广义五边形数的公式和五边形数相同,只是n可以为负数和零,n 依序为0, 1, -1, 2, -2, 3, -3, 4...,广义五边形数也可以用下式表示:
n 依序为0, 1, 2, 3, 4...,
其产生的数列如下:
0, 1, 2, 5, 7, 12, 15, 22, 26, 35, 40, 51, 57, 70, 77, 92, 100, 117, 126, 145, 155, 176, 187, 210, 222, 247, 260, 287, 301, 330, 345, 376, 392, 425, 442, 477, 495, 532, 551, 590, 610, 651, 672, 715, 737, 782, 805, 852, 876, 925, 950, 1001, 1027, 1080, 1107, 1162, 1190, 1247, 1276, 1335... (OEIS:A001318)
在欧拉的整数分拆理论中,五边形数定理说明广义五边形数和整数分拆的关系。
用第n个五边形数(n>2)排列组成的正五边形,外围点的个数有个,因此在内部的点个数为:
刚好也是一个广义五边形数。
所有的整数都可以表示成不超过3个广义五边形数的和[1]。
若三角形数可以被3整除,则除以3之后的数必为广义五边形数[2]。
2、
整数拆分的公式
的生成函数是
当|x|<1,右边可写成:
生成函数的倒数为欧拉函数,利用五边形数定理可得到以下的展开式:
将生成函数配合五边形数定理,可以得到以下的递归关系式
其中是第个广义五边形数。
3、就是利用最后一个公式来做题。注意的是qi是两个部分,最后一个公式也可以写成然后根据这个公式把样例手算一下 ,就很清晰了。
AC代码
/*整数拆分 公式法 打表2017年8月3日00:15:14AC代码*/ #include<stdio.h>#include<iostream>#include<string.h>using namespace std;typedef long long ll;const int mod=1e9+7;const int maxn=1e5+10; ll ans[maxn];int t,n;void init(){memset(ans,0,sizeof(ans));ans[0]=1;for(int i=1;i<=maxn;i++){int f;//代表这一位是加还是捡 for(int j=1;;j++){int a,b;/*i减去对应的两个广义五边形数*/ a=i-j*(3*j-1)/2;b=i-j*(3*j+1)/2;/*根据i判定这一位的正负*/if(j&1) f=1;//奇数 加 else f=-1;//偶数 减/*坑点,如果两个p(n-qi)都小于零,那么就加到这里为止*/ if(a<0&&b<0) break;/*任何一个p(n-qi)大于零都要算进去*/if(a>=0) ans[i]=(ans[i]+f*ans[a]) %mod;if(b>=0) ans[i]=(ans[i]+f*ans[b]) %mod;}ans[i]=(ans[i]+mod)%mod;}}int main(){cin.sync_with_stdio(false);cin>>t;init(); while(t--){cin>>n;cout<<ans[n]<<endl;}return 0;}
再来一个同类型的题目HDU1028
与上面不同的是,不需要模直接输出即可,AC代码
/*2017年8月16日10:07:18HDU1028AC */#include<stdio.h> #include<iostream> #include<string.h> using namespace std; typedef long long ll; //const int mod=1e9+7; const int maxn=1e5+10; ll ans[maxn]; int t,n; void init(){ memset(ans,0,sizeof(ans)); ans[0]=1; for(int i=1;i<=maxn;i++){ int f;//代表这一位是加还是捡 for(int j=1;;j++){ int a,b; /*i减去对应的两个广义五边形数*/ a=i-j*(3*j-1)/2; b=i-j*(3*j+1)/2; /*根据i判定这一位的正负*/ if(j&1) f=1;//奇数 加 else f=-1;//偶数 减 /*坑点,如果两个p(n-qi)都小于零,那么就加到这里为止*/ if(a<0&&b<0) break; /*任何一个p(n-qi)大于零都要算进去*/ if(a>=0) ans[i]=(ans[i]+f*ans[a]) ; if(b>=0) ans[i]=(ans[i]+f*ans[b]) ; } //ans[i]=(ans[i]+mod)%mod; } } int main(){ cin.sync_with_stdio(false); // cin>>t; init(); while(cin>>n){ cout<<ans[n]<<endl; } return 0; }
- HDU4651|HDU1028 Partition 整数拆分公式法
- Partition(hdu4651)2013 Multi-University Training Contest 5----(整数拆分一)
- hdu4651 4658 整数拆分 五边形数定理
- HDU4651 Partition
- hdu4651 Partition
- hdu1028 poj1221 母函数 整数的拆分
- HDU1028整数拆分(母函数)
- hdu 4651Partition(整数拆分模板题)
- hdu 4658 Integer Partition(整数拆分变形)
- hdu 5646 DZY Loves Partition(整数拆分)
- hdu 4651 Partition 整数划分+公式
- hdu 4651 (整数拆分 公式题)
- hdu4651
- HDU1028 Ignatius and the Princess III(整数拆分:母函数||DP)
- hdu1028 整数划分
- HDU 4602 Partition (整数拆分&找规律&快速幂取模)
- HDU1028 拆分数母函数
- 整数拆分-递归法
- Java中ThreadPoolExecutor的详细介绍
- java基础复习-时间
- 习题 3.3 购房从银行贷了一笔款d, 准备每月还款额为p, 月利率为r, 计算多少月能还清。设d为300000元,p为6000元,r为1%。对求得的月份取小数点后一位,对第2位按四舍五入处理。
- [绍棠_Swift] Swift3.0中tableviewcell分割线显示不全解决方案
- Spring注解详解
- HDU4651|HDU1028 Partition 整数拆分公式法
- Centos7上搭建SVN服务器并实现自动同步至web目录
- 数据冒险之二叉树(数组)
- Java并发容器大合集
- kafka参数配置
- java基础复习-线程
- C# 将文本写入txt文件中
- 如何选择与设置域名?
- 『谷粒儿』-有它,育儿就是这么简单