整数划分和放苹果问题
整数划分问题和正整数连续划分问题:http://www.cnblogs.com/nokiaguy/archive/2008/05/11/1192308.html讲的很细致
放苹果问题:把m个苹果放到n个盘子里,允许有空,有多少种放法http://acm.tzc.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=2679
递归方程:f(m,n) = f(m,n-1) + f(m-n,n) //每次分有两种分法
f(m,n-1):把m个苹果放到n-1个盘子里,也就是说至少有一个空
f(m-n,n):先在每个盘子里放一个苹果,然后再把剩余苹果(m-n)放到n个盘子里,也就是说每个盘子里至少有一个
1.n == 1 || m == 1 即只有一个盘子或者只有一个苹果,显然只有一种分法;
2.m < n 即苹果数小于盘子数,这种情况f(m,n) ---> f(m,m)
3.m == n 此时每个盘子里至少一个只有一种情况所以为 1 + f(m,n-1)
4.m > n f(m,n-1) + f(m-n,n) (如一开始所说)
#include <stdio.h>
int f(int m , int n)
{
if(m == 1 || n== 1 || m == 0) return 1;
if(m < n) return f(m, m);
return f(m - n, n) + f(m, n - 1);
}
int main(void)
{
int n , m , z;
scanf("%d", &z);
while(z-- > 0)
{
scanf("%d%d", &m ,&n);
printf("%d\n",f(m, n));
}
return 0;
}
对于整数的连续划分我自己也写了个:
i * x + i * (i - 1) / 2 = n (i为划分个数,x为起始数);
i * (i + 1) / 2 <= n (i的上限);
#include <stdio.h>
void split(int n)
{
int i , t , x , k;
for(i = 1 ; (t = i * (i - 1) / 2) < n ; i++)
{
if(n - t < 0 || (n - t) % i) continue;
x = (n - t) / i;
for(k = 0 ; k < i ; k++)
{
printf(k == i - 1 ? "%d\n" : "%d + ", x + k);
}
}
}
int main(void)
{
int n;
scanf("%d", &n);
split(n);
return 0;
}