N个鸡蛋放M个篮子,每个篮子不空,保证提不同组合的篮子能取出1至N个鸡蛋。输出所有可能的放法。
例如6个鸡蛋放入3个篮子,则1,2,3能满足条件。
如8个鸡蛋放入4个篮子,则1,1,2,4能满足条件,1,2,2,3也能满足条件。
深度优先方法解答。假设按顺序篮子里的鸡蛋个数是呈现递增。
如第一个肯定是1,第二个篮子呢,只能是1或者2;
如果第二个篮子是1,则第三个篮子可以是1≤x≤3;
如果第二个篮子是2,则第三个篮子是2或者3;
如果第一个篮子是1,第二个篮子是2,第三个篮子是3,那么第四个篮子呢,最小肯定只能是3,最大呢,只能是(1+2+3)+1.
边界条件:
如果N < M,肯定是不存在此类的方法;
如果N == M,则每个篮子只能是1个了;
数组a[0] = 2^0, a[1] = 2^1, a[n]=2^n. 当N < sum(a[0]+a[1] +...+a[M]) 时,同样不存在此类方法。1,2,4,8,16,32,64,...
currentLevel 表示visit到了该层,这层我们只能放currentValueMin <= egg <= alreadyMax+1 个鸡蛋。currentEgg表示到该层为止还剩下多少可用的egg。alreadyMax表示至该层为止已经能够取到的1至N最大的鸡蛋数。
#include "stdafx.h"
#include <iostream>
using namespace std;
int N = 29;
int M = 6;
int *basket;
int sum = 0;
void DepthVisit(int currentValueMin, int currentLevel, int currentEgg, int alreadyMax)
{
if(currentLevel == M)
{
if(currentEgg == 0 && alreadyMax == N)
{
cout<<++sum<<" : ";
for(int i=0; i<M; i++)
cout<<basket[i]<<" ";
cout<<endl;
}
return;
}
if(currentEgg < 0 || alreadyMax > N || currentLevel > M)
return;
for(int i=currentValueMin; i <= alreadyMax + 1; i++)
{
basket[currentLevel] = i;
DepthVisit(i, currentLevel+1, currentEgg - i, alreadyMax + i);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
basket = new int[M];
basket[0] = 1;
DepthVisit(1, 1, N-1, 1);
system("pause");
return 0;
}