• 蓝桥杯 数的划分两种解法


    问题描述

    将整数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

    个人见解:这道题第一次我写了递归的方法,但是我想用动规做一下,然后真成了,对于这道题来说,个人建议用递归,因为这题数字范围并不是很大,下面贴上两种实现代码。
    题目传送:数的划分

    递归版代码实现

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    
    public class Main {
        public static void main(String[] args) throws IOException {
            BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
            String[] s = reader.readLine().split(" ");
            int n = Integer.parseInt(s[0]),k=Integer.parseInt(s[1]);
            System.out.println(dfs(1,k,n));
        }
        /**
         * @param x 代表上一个取出的数,初始值为1
         * @param k 代表分成的份数还剩多少份,如果剩1份,种数就是1了
         * @param n 表示还剩多大
         */
        private static int dfs(int x, int k, int n) {
            if (k==1) {
                return 1;
            }
            int sum = 0;
    
            for (int i = x; i <=n/k; i++) {
                sum+=dfs(i, k-1, n-i);
            }
            return sum;
        }
    }

    dp版代码实现

    我的想法:以一个数为基准,逐步减少分割数或减少待分割数这里选取1为基准

     得出f[i][j]=f[i-1][j-1]+f[i-j][j](i>=j),f[i][j]=0(i<j).记得f[i][i]=1(范围1-n)

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    
    public class Main {
        public static void main(String[] args) throws IOException {
            BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
            String[] s = reader.readLine().split(" ");
            int n = Integer.parseInt(s[0]);
            int k = Integer.parseInt(s[1]);
            int dp[][] = new int[n+1][k+1];
            //dp[i][j]表示将i分成j份的方法种数
            //初始化:当i=j或j=1的时候,则只有一种分法;
            for (int i = 1; i <=n; i++) {
                dp[i][1] = 1;
            }
            //当i>j时,我们可以转化为   有1的情况+没有1的情况
            //(1)当i>j时  则有dp[i][j] = dp[i-1][j-1]+dp[i-j][j];
            //(2)当i=j时 则有1种分法
            //(2)当i<j时 则有0种分法
            for (int i = 1; i <=n; i++) {
                for (int j = 1; j <=k; j++) {
                    if (i==j)dp[i][j] = 1;
                    if (i>j)dp[i][j] = dp[i-1][j-1]+dp[i-j][j];
                }
            }
            System.out.println(dp[n][k]);
        }
    }
    如果觉得这篇文章有帮助的话,希望可以在右边点个赞,关注一下下也是可以的
  • 相关阅读:
    [Angular] @ContentChild and ngAfterContentInit
    [Angular] Content Projection with ng-content
    [ES2016] Check if an array contains an item using Array.prototype.includes
    [Ramda] Handle Errors in Ramda Pipelines with tryCatch
    [React Native] Installing and Linking Modules with Native Code in React Native
    [Ramda] Refactor to Point Free Functions with Ramda using compose and converge
    [React Native] Writing Platform-Specific Components for iOS and Android in React Native
    [Redux] Avoid action type naming conflicts
    paip.索引优化---sql distict—order by 法
    DL,DT,DD,比传统table更语义,解析更快的table列表方式
  • 原文地址:https://www.cnblogs.com/xuewen1999/p/shudehuafen.html
Copyright © 2020-2023  润新知