3个人分12个月饼,可以理解为:
1个人分1个月饼 + 后续2个人分11个月饼
1个人分2个月饼 + 后续2个人分10个月饼
1个人分3个月饼 + 后续2个人分9个月饼
1个人分4个月饼 + 后续2个人分8个月饼 (4 + 4 + 4 结束,因为这里可以理解为要求递增数列)
从以上排序中筛除不符合题目要求的序列
因此递归的基础是2个人分n个月饼
#include <iostream>
using namespace std;
/// @brief 分月饼的方法
/// @param fellow 参与分月饼的人数
/// @param pie 月饼个数
/// @param limit 这群人中分得的月饼数量不低于limit
/// @return 以上条件下的分配方法
int divide_pie(int fellow, int pie, int limit)
{
int divide_ways = 0;
if (fellow == 1)
{
divide_ways = 1;
return divide_ways;
}
// 对于2个人来说
if (fellow == 2)
{
int two_man_allocate[2];
two_man_allocate[0] = limit;
two_man_allocate[1] = pie - limit;
while (two_man_allocate[0] <= two_man_allocate[1])
{
// 要求
if (two_man_allocate[1] <= two_man_allocate[0] + 3 &&
two_man_allocate[0] <= limit + 3)
{
divide_ways += 1;
}
if (two_man_allocate[0] + 1 > two_man_allocate[1] - 1)
{
break;
}
two_man_allocate[0] += 1;
two_man_allocate[1] -= 1;
}
return divide_ways;
}
// 多个人
else
{
// 对于3个人分12个月饼可以这么考虑:
// 情况1:1个人分1个月饼,剩下2个人分11个月饼
// 情况2:1个人分2个月饼,剩下2个人分10个月饼
// 情况3:1个人分3个月饼,剩下2个人分9个月饼
// 情况4:1个人分4个月饼,剩下2个人分4个月饼 (这两个人分得月饼都不应小于1个人的4个月饼,结束)
// 计算出 fellow 个人分配 pie 个月饼时第一个人(最少分得月饼的那个人)所能够达到的最大值
// 比如 11块月饼分给4个人,第一个人最多能分2块,此时:2 + 3 + 3 + 3
// 比如 12块月饼分给4个人,第一个人最多能分3块,此时:3 + 3 + 3 + 3
// 比如 13块月饼分给4个人,第一个人最多能分3块,此时:3 + 3 + 3 + 4
int first_man_has_pie_max = pie / fellow;
int first_man_has_pie = limit; // 尤其注意因为迭代输入,这里的第一个人其实是第2个人,因此其起点应该从limit开始
do
{
divide_ways += divide_pie(fellow - 1, pie - first_man_has_pie, first_man_has_pie);
first_man_has_pie++;
} while (first_man_has_pie_max >= first_man_has_pie);
return divide_ways;
}
}
// 分月饼
static void HuaWei_OD_test28(void)
{
int fellow_cnt, pie_cnt;
cin >> fellow_cnt >> pie_cnt;
int valid_divide_ways = 0; // 合理的分法
valid_divide_ways = divide_pie(fellow_cnt, pie_cnt, 1);
cout << valid_divide_ways << endl;
}
int main()
{
HuaWei_OD_test28();
return 0;
}