算法小菜鸟刚开始做POJ,1664是一个关于整数拆分的问题,即:
将正整数n拆分成k个不能整数的和,0<=k<=n,求有多少种差分方法。
比如:将7差分成3个不同整数的拆分法有8中,其中1,1,5和1,5,1属于同一种拆分法。
该问题等同于:
将n个完全相同的物品放到k个完全相同的容器中,求有多少种方法。
由于小菜鸟数学不好,感觉是用递推,但总是写不出正确的递推公式,于是google之:
http://hi.baidu.com/roba/blog/item/566f5bb58525d5cc37d3ca42.html/cmtid/eb5d6b63afb0c86a0c33fa97
如果我们用opt[i][j]表示把i拆成j个数(可为0)的方法数,则有如下方程成立:
opt[i][j] = opt[i][j-1] + opt[i-j][j]
边界条件opt[0][j] = 0
解释为,
(1)要么第j个数为0,这样就是opt[i][j-1],(存在被分配数为0的j)
(2)要么所有的j被分配数都大于0(最小的j被分配的数大于0),我们可以把所有j个数都减1,于是得到opt[i-j][j]。
等同于:
①最少的盘子没有放,这样剩下的k-1个盘子还是随便放n个
②最少的盘子放了一个,这样每个盘子至少一个,k个盘子先放上k个,剩下的n-k个可以随便放
可以做到空间为O(N)。代码也很好写。