整数划分



题目描述:

整数划分是一个经典的问题,希望这道题对你的组合数学有所帮助. 提示 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");
}
  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值