hdu 4658 Integer Partition 整数划分+生成函数
来源:互联网 发布:级域名泛解析多久生效 编辑:程序博客网 时间:2024/04/25 08:40
#include <stdio.h>#include <math.h>#include <string.h>#include <iostream>using namespace std;const int mod=1e9+7;int f[100010];void init(){ f[0]=1; int i,j,k,flag,t,tt; for(i=1;i<=100000;i++) { f[i]=0; flag=1; for(j=1;;j++) { t=i-j*(3*j-1)/2; tt=i-j*(3*j+1)/2; if(t<0)break; f[i]=(f[i]+flag*f[t])%mod; if(tt<0)break; f[i]=(f[i]+flag*f[tt])%mod; flag=-flag; } f[i]=(f[i]+mod)%mod; }}int find(int n,int k){ int i,j,ans,flag=-1,t,tt; ans=f[n]; for(i=1;;i++) { t=k*i*(i*3-1)/2; tt=k*i*(i*3+1)/2; if(t>n)break; ans=(ans+flag*f[n-t])%mod; if(tt>n)break; ans=(ans+flag*f[n-tt])%mod; flag=-flag; } return (ans+mod)%mod;}int main(){ init(); int T; cin>>T; while(T--) { int n,k,ans; scanf("%d%d",&n,&k);//T很大,不要用cin和cout ans=find(n,k) ; printf("%d\n",ans); } return 0;}
将n拆分成多个正整数之和,问有多少种拆法?
如5=1+1+1+1+1=1+1+1+2=1+1+3=1+4=5=1+2+2=2+3.共7种
方法:
直接公式:f[n]=∑(-1)^(k-1)*(f[n-k*(3*k-1)/2]+f[n-k*(3*k+1)/2])
其中n-k*(3*k-1)/2>=0,n-k*(3*k+1)/2>=0;
注意两个条件要分开判断,有大于0的就加上相应的f,不是两个同时成立或者不成立
以上是求的是无限制的整数划分
本题要求,拆分出来的整数中,任意整数都不能出现k次或k次以上,因而需要用公式的推导原理——生成函数来求
生成函数的详细说明请去百度百科或者维基百科查看,这里只简要说明下:
生成函数(也有叫做“母函数”的)是说,构造这么一个多项式函数g(x),使得x的n次方系数为f(n)。
这题用到的1+x+x^2+...,f[n]就是全由1组成的n有多少种,显然是1.类似的1+x^2+x^4+..表示的就是全部由2组成,
两者相乘的意义就在于(1+x+x^2)*(1+x^2)=1+x+2*x^2+x^3+x^4,其中x^2系数2表示拆分整数2的方案数,2=1+1=2,共2种
所以无限制的拆分就可以理解成(1+x+x^2+x^3+...)*(1+x^2+x^4+..)*..*(1+x^k+x^2k+...)*..中x^n的系数就是所求值
这题加了k的限制,所以得到的生成函数式:
(1+x+x^2+...+x^(k-1))*(1+x^2+x^4+x^2(k-1))*...(每个括号内斗是等比数列求和)
=(1-x^k)/(1-x)*(1-x^2k)/(1-x^2)*(1-x^3k)/(1-x^3)...(令y=x^k)
=∏(1-y^i)/∏(1-x^i)(1<=i<∞)=g[y]/g[x]
∏(1-x^i)形式的可用五边形数定理来求,详细的请百度和谷歌
五边形定理:
再由可知
1/g[x]的系数
即p[n]=∑(-1)^(k-1)*(p[n-k*(3*k-1)/2]+p[n-k*(3*k+1)/2]),dp一下就能出来了
之后答案就是求(1-x^k-x^2k+x^5k+x^7k-x^12k-x^15k+x^22k+x^26k)*(1+p(1)x+p(2)x+p(3)x+...)中x^n的系数了
前者用五边形数定理求出指数x和系数flag,找到∑p[n-x]*flag就是结果了
相关链接:http://blog.csdn.net/zhoufenqin/article/details/9821617这位大神写的很详细,没看懂的可以去这看看]
- hdu 4658 Integer Partition 整数划分+生成函数
- 记 整数划分(integer partition)
- 2013 多校第六场 hdu 4658 Integer Partition(五边形数定理,整数划分)
- HDOJ 4658 Integer Partition(整数划分:母函数+五边形数定理)
- 【HDU】4658 Integer Partition【生成函数——数拆分】
- hdu 4658 Integer Partition(整数拆分变形)
- 整数划分 Integer Partition(一)
- HDU 4658 Integer Partition
- hdu 4658Integer Partition
- hdu 4658 Integer Partition
- HDU 4658 Integer Partition
- HDU-4658-Integer Partition
- hdu 4651 Partition 整数划分+公式
- HDU 4651 Partition(整数划分)
- hdu 4671 Partition(DP,整数划分,5级)
- [HDU 4602]Partition[划分]
- hdu 4658 Integer Partition(公式)
- [五边形数定理 DP] 51Nod 1259 整数划分 V2 & HDU 4651 Partition
- Objective-C ,ios,iphone开发基础:在UITextField输入完以后,隐藏键盘,
- Ubantu 使用disks工具全盘格式化之后数据恢复
- 【算法】KMP模式匹配算法
- Linux Shell中各种分号和括号的用法总结
- Node.js-require的使用方法
- hdu 4658 Integer Partition 整数划分+生成函数
- android 缓存Bitmap - 开发文档翻译
- javascript 把字符串转换成json对象
- Nginx-ngx_queue
- Android SDK下载和更新失败的解决方法!!!
- 飘逸的python - 性能调优利器profile及其意义
- jquery, json与ashx的完美结合
- 修改Eclipse启动图标
- 矩阵算法模板