• 划分整数


     

    题目描述

    将整数n分成k份,且每份不能为空,任意两个方案不相同(不考虑顺序)。

    例如:n=7k=3,下面三种分法被认为是相同的。

    1,1,5
    1,5,1
    5,1,1

    问有多少种不同的分法。

    输入格式

    n,k (6<n200,2k6)

    输出格式

    1个整数,即不同的分法。

    输入输出样例

    输入 #1
    7 3
    
    输出 #1
    4
    

    说明/提示

    四种分法为:
    1,1,5
    1,2,4
    1,3,3
    2,2,3

     

     代码:1采用深度优先算法

    #include<iostream>
    using namespace std;
    int n,k,ans;
    void dfs(int past,int cnt,int num){
        if (cnt==1)
        {
            ans++;
            return ;
        }
        for (int i = past; i <= num/cnt; i++)
            dfs(i,cnt-1,num-i);    
    }
    int main(){
        cin>>n>>k;
        dfs(1,k,n);
        cout<<ans<<endl;
    }

     

    代码2:采用dp的方法

    f[i][x] 表示 i 分成 x 个非空的数的方案数。

    显然 i<x 时 f[i][x]=0 , i=x 时 f[i][x]=1;

    其余的状态,我们分情况讨论:

    ①有1的 ②没有1的

    第一种情况,方案数为 f[i-1][x-1]

    第二种情况,方案数为 f[i-x][x] (此时 i 必须大于 x)

    所以,状态转移方程为: f[i][x]=f[i-1][x-1]+f[i-x][x]

     

    代码2:动态规划dp

    #include<bits/stdc++.h>
    using namespace std;
    int n,k,f[201][7];  //f[k][x] k 分成 x 份 ={f[k-1][x-1],f[k-x][x]}
    int main(){
        cin >> n >> k;
        for (int i=1;i<=n;i++) {
            f[i][1]=1;
            f[i][0]=1;
        }
        for (int x=2;x<=k;x++) {
            f[1][x]=0;
            f[0][x]=0;
        }  // 边界,为了防止炸,我把有0的也处理了
        for (int i=2;i<=n;i++){
            for (int x=2;x<=k;x++)
                if (i>x) {
                    f[i][x]=f[i-1][x-1]+f[i-x][x];
                else 
                    f[i][x]=f[i-1][x-1];
        }
        cout<<f[n][k];
        return 0;
    }

     

    代码3:母函数

     

     

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <math.h>
    #include <stdbool.h>
    
    #define max(A, B) ((A > B) ? A : B)//习惯携带,自行忽略 (*゚▽゚*)
    #define min(A, B) ((A > B) ? B : A)
    
    int main()
    {
        freopen("Hardict_in.txt", "r", stdin);
        freopen("Hardict_out.txt", "w", stdout);
        int n, dv;
        int i, j, k, l;
        int value[233][233], temp[233][233] = { 0 };
        scanf("%d%d", &n, &dv);
    
        memset(value, 0, sizeof(value));
        for (i = 0; i <= dv; i++)
            value[i][i] = 1;//初始化,全为1可行(设置边界)
    
        for (i = 2; i < n; i++) {
            for (j = 0; j <= n; j++)
                for (l = 0; l <= dv; l++)//取到dv就停止
                    for (k = 0; k + j <= n; k += i)
                        temp[k / i + l][k + j] += value[l][j];//如果不能理解可以试试写写或看一维的(推荐自己写几项,一维的我贴在下面了)
    
            for (l = 0; l <= dv; l++){
                for (j = 0; j <= n; j++){
                    value[l][j] = temp[l][j];
                    //printf("%d ",value[l][j]);
                }
                //printf("%d   
    ",l)可以打表观察变化
            }
                    }
            memset(temp, 0, sizeof(temp));//temp设置为0,进行x^(i+1)系列的读入
        }
    
        printf("%d", value[dv][n]);
        return 0;
    }

    一维的:

    int n, value[2333], temp[2333];
        int i, j, k;
        scanf("%d", &n);
    
        for (i = 1; i <= n; i++)
            value[i] = 1; //x^1时,即第一个括号中
    
        for (i = 2; i <= n; i++) {
            memset(temp, 0, sizeof(temp));
            for (j = 0; j <= n; j++)
                for (k = 0; k + j <= n; k += i)
                    temp[k + j] += value[j];
    
            for (j = 0; j <= n; j++)
                value[j] = temp[j];
        }
        printf("%d", value[n]);//这里求的是所有能构成n的划分个数

     

     

     

     

     

     

     

    G(x)=(1+yx+y2x2+y3x3+y4x4+.....)(1+yx2+y2x4+y3x6+y4x8+......)(1+yx3+y2x6+y3x9+....)........(1+yxn)

    因上求缘,果上努力~~~~ 作者:每天卷学习,转载请注明原文链接:https://www.cnblogs.com/BlairGrowing/p/12764777.html

  • 相关阅读:
    03 在百度地图上定位到指定位置
    01 如何将百度地图加入IOS应用程序?
    三个字理解委托机制
    iOS 应用程序打包、真机调试 方法
    在读iOS官方文档时,里面有很多你不懂的单词,不要担心
    用“大控件”与“大数据类型”思想来理解view Cotroller
    04 将当前位置用大头针标注到百度地图上
    02 使用百度地图获得当前位置的经纬度
    专注分享思考过程
    像孙正义为了练英语坚决不说日语一样。我也应该有坚决不看中文文档的心!
  • 原文地址:https://www.cnblogs.com/BlairGrowing/p/12764777.html
Copyright © 2020-2023  润新知