题目描述:整数划分是一个经典的问题,希望这道题对你的组合数学有所帮助. 提示 1. 将5划分成若干正整数之和的划分为: 5, 4+1, 3+2, 3+1+1, 2+2+1, 2+1+1+1, 1+1+1+1+1 2. 将5划分成2个正整数之和的划分为: 3+2, 4+1 3. 将5划分成最大数不超过2的划分为: 1+1+1+1+1, 1+1+1+2, 1+2+2 4. 将5划分成若干奇正整数之和的划分为: 5, 1+1+3, 1+1+1+1+1 5. 将5划分成若干不同整数之和的划分为: 5, 1+4, 2+3 |
输入描述:每组输入是两个整数n和k。(1<=n<=50,1<=k<=n) |
输出描述:对于每组输入,请输出6行第一行: 将n划分成若干正整数之和的划分数。 第二行: 将n划分成k个正整数之和的划分数。 第三行: 将n划分成最大数不超过k的划分数。 第四行: 将n划分成若干奇正整数之和的划分数。 第五行: 将n划分成若干不同整数之和的划分数。 第六行: 打印一个空行 |
#include <stdio.h>
#include <string.h>
const int maxn = 51;
int n, k, f[maxn][maxn], g[maxn][maxn];
int f1[maxn][maxn], f2[maxn][maxn];
int main ()
{
int i, j;
int ans1, ans2, ans3, ans4, ans5;
f1[0][0] = 1;
for (i = 1; i < maxn; i ++)
for (j = 1; j <= i; j ++)
f1[i][j] = f1[i - j][j] + f1[i - 1][j - 1];//f(n,m)=f(n-m,m)+f(n-1,m-1);
f[0][0] = g[0][0] = 1;
for (i = 1; i < maxn; i ++)
for (j = 1; j <= i; j ++)
{
g[i][j] = f[i - j][j];
f[i][j] = f[i - 1][j - 1] + g[i - j][j];
}
for (i = 0; i < maxn; i ++)
f2[i][0] = 1;
for (i = 1; i < maxn; i ++)
for (j = 1; j < maxn; j ++)
{
f2[i][j] = f2[i - 1][j];
if (j - i >= 0)
f2[i][j] += f2[i - 1][j - i];
}
while (scanf ("%d %d", &n, &k) != EOF)
{
ans1 = ans2 = ans3 = ans4 = ans5 = 0;
for (i = 1; i <= n; i ++)
ans1 += f1[n][i];
ans2 = f1[n][k];
for (i = 1; i <= k; i ++)
ans3 += f1[n][i];
for (i = 1; i <= n; i ++)
ans4 += f[n][i];
ans5 = f2[n][n];
printf ("%d\n%d\n%d\n%d\n%d\n", ans1, ans2, ans3, ans4, ans5);
}
return 0;
}
若只求将n划分成若干正整数之和的划分数。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
__int64 a[150];
int main()
{
int i,j;
a[0]=1;//a[1]=1;a[2]=2;a[3]=3;a[4]=5;a[5]=7;
for(i=1;i<=120;i++)
{
for(j=0;i+j<=120;j++)
{
a[i+j]+=a[j];
}
}
int n;
while(scanf("%d",&n)!=EOF)
{
printf("%I64d\n",a[n]);
}
return 0;
}
若求具体划分集合:
#include<stdio.h>
int x[50]={0};
int main()
{
void split(int n,int k);
int n;
printf("Please input 'n'(0<n<100):");
scanf("%d",&n);
split(n,0);
}
void split(int n,int k)//k是数组中的位置,亦是递归层数
{
void display(int k);
int i;
if(n==0)//分解完成,输出结果
display(k);
else
for(i=n;i>0;i--)
if(k==0||i<=x[k-1])
{
x[k]=i;//写入数组
split(n-i,k+1);
}
}
//输出数组前k项
void display(int k)
{
int i;
for(i=0;i<k;i++)
printf("%d ",x[i]);
printf("\n");
}