整数分拆
n个数拆分(无序)最多拆成n份正整数(有0另外算)
有多少种呢?
假设x拆成k份
可以由
每一种情况的
x-k拆成k份的k份中每一个整数+1
和
每一种情况的
x-1拆成k-1份,且新建一份,在第k份中的整数为1
这两种情况的和得来
由于拆成k份直接变来的都包含在x-k拆成k份中了,少于x-k的x-k是由前面的推来的,前面的情况都包括了
小于x-k的等价于某几份多加了几个1,大于x-k的情况包含在x-k中是因为等价于某几份少加了几个1
且直接用用大于x-k的来算不知道是哪一份少几个+1,不方便!同样小于x-k的不知道是哪一份多几个+1
由于考虑了每一种情况x-2拆成k-2份另建2份都放1,肯定已经包含在了x-1拆成k-1份中,小于k-1份的也包含在了k-1份中了
又由于拆成k份只能由少于k份的增加得来
所以
求n能拆成的种数为拆成1份加到拆成n份的种数
dp[0][0]=1;
for(int i=1;i<=n;i++)
for(int j=1;j<=i;j++)
dp[i][j]=dp[i-j][j]+dp[i-1][j-1];
for(int i=1;i<=n;i++)s+=dp[n][i];
假如能在某一份中为0的话,
就会出现大于n份
一样的
因为有无穷多份,所以总会让你求多少份假如是m份
大于n份的按n份算
小于n的从拆成1份加到m份的
因为小于m份的可以补0
for(int i=1;i<=min(n,m);i++)s+=dp[n][i];
假如只能拆分成小于等于m的数,可以利用一下
m>n的数字用不到,就按m=n算
f(n,n)=f(n,n-1)+1;就是这个数本身
m<n
最大能取到m所以至少可以取一个m剩下的等于用f(n,m-1)最大只有m-1的和f(n-m,m)少了个m最大依旧为m的和
f(n,m)=f(n,m-1)+f(n-m,m);
n>=1
f(n,1)=1;
如果是拆分成l到r中的某些数就用
f(n,r)-f(n,l-1);
由于整数分拆这个是一个古老的问题了,很久前的各路大大
研究了用五边形数的方法求达到了O(n)
下次再弄,证明完全不会- -!
有序拆分的话
把n拆成小于等于n的任意的话种数为2^n-1
把n拆成m份的话,种数位C(n-1,m-1)相当于把n分n个1,n-1个间隔插m-1个板子的方案数
把n拆成小于等于m的数的种数为
相当于把最后一个数看成新加入的为1-m所有情况的和
不需要上面的那种全部加1的方法了,因为这个没有确定份数,全部+1的方案也包含在最后一位为(1-m)中某个数减一后加一或者多一份为一
for(int i=1;i<=n;i++)
for(int j=i+1;j<=m;j++)
dp[i]+=dp[i-j];
其实这个好像也能推出公式的。。。
f(n,m)中n<=m时能弄出
f(n,m)=f(n-1,m)*2;
n>m时
for(int i=n-m;i<=n-1;i++)f(n,m)+=f(i,m);
这里好像能弄出f(n,m)=m项2(的奇数次幂)的和;
好像也有这样的公式
用快速幂就能到log(n)了
浙公网安备 33010602011771号