在图书馆书上看到的一个题目,书上是用别的方法做的,我的第一感觉是用dfs,分析了一下,很有收获,总结下。
整数拆分问题,比如6可以拆分为:
6=6
6=5+1
6=4+2
6=4+1+1
6=3+3
6=3+2+1
6=3+1+1+1
6=2+2+2
6=2+2+1+1
6=2+1+1+1+1
6=1+1+1+1+1+1
有11种
我的想法是拆分序列可以递增或递减,上面的就是递减的,这种就是递增的
6=1+1+1+1+1+1
6=1+1+1+1+2
6=1+1+1+3
6=1+1+2+2
6=1+1+4
6=1+2+3
6=1+5
6=2+2+2
6=2+4
6=3+3
6=6
ok,这个思路的代码分别是:
void fun1(int n)
{//递减
if(n<0) return;
if(n==0) ans++;
int i;
for(i=n;i>=1;i--)
{
fun1(n-i);
}
}
void fun2(int n)
{//递增
if(n<0) return;
if(n==0) ans++;
int i;
for(i=1;i<=n;i++)
{
fun2(n-i);
}
}
这个n的意义是将整数n进行拆分,但是像上面的思路会产生重复,比如:4=2+1+1,4=1+2+1,还有其他类似的情况。
为了防止这类情况的发生,可以将结点值保存下来,传递到子结点,保证子结点的值小于其父结点,同理,递增的一样。
对应的代码:
void fun1(int n,int k)
{//递减
if(n<