ALGO-22 数的划分

ALGO-22 数的划分

题目

资源限制

内存限制:256.0MB C/C++时间限制:1.0s Java 时间限制:3.0s Python 时间限制:5.0s

问题描述

将整数 n 分成 k 份,且每份不能为空,任意两份不能相同(不考虑顺序)。
例如:n=7,k=3,下面三种分法被认为是相同的。
1,1,5; 1,5,1; 5,1,1;
问有多少种不同的分法。

输入格式

n,k

输出格式

一个整数,即不同的分法

样例输入

7 3

样例输出

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

数据规模和约定

6<n<=200,2<=k<=6

代码

思路

\(dp[i][j]\)表示将数 \(i\) 分成 \(j\)
情况分为两种有\(1\)和没\(1\)的情况

\(1\)的情况: \(dp[i-1][j-1]\)
\(1\)的情况: \(dp[i-j][j]\)

所以 \(dp[i][j]=dp[i-1][j-1]+dp[i-j][j]\)

Java

import java.util.Scanner;

public class ALGO_22 {
    static int ans = 0, n, k;

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        n = scanner.nextInt();
        k = scanner.nextInt();
        scanner.close();
        dfs(0, 0, 1);
        System.out.println(ans);
        System.out.println(divide(n, k));
    }

    /**
     * 递归
     * @param {*}
     * @return {*}
     */
    private static void dfs(int t, int a, int b) {
        {
            if (a == n || t == k){
                if (a == n && t == k)
                    ++ans;
                return;
            }
            for (int i = b; i <= n - a; i++)
                if (a + i <= n)
                    dfs(t + 1, a + i, i);
        }
    }

    /**
     * 动态规划
     * @param {int} n
     * @param {int} k
     * @return 结果
     */
    private static int divide(int n, int k) {
        int[][] dp = new int[n + 1][k + 1];
        dp[0][0] = 1;
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= k; j++) {
                if (i >= j)//当前要划分的数得大于划分的份数
                    dp[i][j] = dp[i - j][j] + dp[i - 1][j - 1];
            }
        }
        return dp[n][k];
    }
}
posted @ 2022-04-06 09:14  morning-start  阅读(27)  评论(0编辑  收藏  举报