把一个给定的整数n划分成m个整数的问题:
Partitioning a given integer n into unique partitions of size m.
like if n=10,m=4, 7 1 1 1 is one such partition. Give all such partitions。
(这里要求不要给出重复的划分,比如5 2 2 1 与 5 1 2 2就是重复的划分。)
#include
int buf[1024]; //数组长度只需大于等于 m 即可
int bp;
void part(int n, int m, int min) //这里设置min值,保证了后划分出来的值要小于等于
//先划分出来的值,从而防止重复。
{
int i;
if (m == 0 && n == 0) {
for (i = bp - 1; i >= 0; i--) printf("%d ", buf[i]);
printf("\n");
}else if (m > 0) {
for (i = min; i <= n; i++) {
if(m == 1 && n>i){ //这里的判断是为了减少调用part()次数而写的,
buf[bp] = n; //为了便于理解,可以把这几句删除。
}else{ //
buf[bp++] = i;
part(n - i, m - 1, i);
bp--;
}
}
}
}
int main(void)
{
bp = 0;
part(10, 4, 1);
return 0;
}
这里,我又想起了很类似的一个问题,从无限多个一模一样的球中取n个球,分m次取,列出所有取法?
即第一次取几个,第二次取几个......第m次取几个。
这个问题与把整数n划分成m个正整数类似,不同点在于划分正整数时,5 2 2 1 与5 1 2 2是同一个划分,
但取球时,5 2 2 1 与 5 1 2 2是不同的取法。
总共有C(n-1,m-1)中取法。
具体列出取法:
这时只需要把min参数改动即可。
#include
int buf[1024]; //数组长度只需大于等于 m 即可
int bp;
void part(int n, int m)
{
int i;
if (m == 0 && n == 0) {
for (i = bp - 1; i >= 0; i--) printf("%d ", buf[i]);
printf("\n");
}else if (m > 0) {
for (i = 1; i <= n; i++) {
if(m == 1 && n>i){
buf[bp] = n;
}else{
buf[bp++] = i;
part(n - i, m - 1, i);
bp--;
}
}
}
}
int main(void)
{
bp = 0;
part(10, 4, 1);
return 0;
}
阅读(867) | 评论(0) | 转发(0) |