蓝桥杯 数的划分两种解法

问题描述

将整数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]);
    }
}

 

posted @ 2018-04-02 09:38  xuewenのblog  阅读(1066)  评论(0编辑  收藏  举报