使用记忆化/动态编程的 Java 组合学

标签 java dynamic-programming combinatorics memoization

我正在编写一个程序,给出给定两个数字的可能组合的数量,例如 N 选择 K。我有一个递归解决方案,如下所示:

public static int combinations(int group, int members) {
    if (members == 1) {
        return group;
    }
    else if (members == group) {
        return 1;
    }
    else {
        return(combinations(group - 1, members - 1) + 
                combinations(group - 1, members));
    }
}

这个可行,但我需要使用内存来提高时间复杂度并加快更大数字的速度,但我不知道如何去做。我该如何去做呢?

最佳答案

根据公式n 选择 k = ( n - 1 选择 k - 1) + ( n-1 选择 k ) 自下而上的动态规划方法是:

dp[n][k] = dp[n-1][k-1] + dp[n-1][k] if n > k 
else if n == k
dp[n][k] = 1
else
dp[n][k] = 0

n = 1k = 1开始

dp[1][1] = 1; dp[1][0] = 1; 

然后填充一个二维数组,直到dp[n][k]

就像您的情况一样,也可以通过内存来完成。您的方法可以更改为:

int[][] dp = new int[group][members];

public static int combinations(int group, int members, int[][] dp ) {

    if (members == 1) {
        return group;
    } else if (members == group) {
        return 1;
    }

    if ( dp[group][members] != 0 ) {
       return dp[group][members];
    }

    int first = 0, second = 0;
    if ( members <= group - 1) {
      first = combinations( group - 1, members - 1, dp );
      second = combinations( group - 1, members );
    } else if ( members - 1 <= group - 1 ) {
      first = combinations( group - 1, members - 1, dp );
    }
    dp[group][members] = first + second;

    return dp[group][members];
}

关于使用记忆化/动态编程的 Java 组合学,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53182377/

相关文章:

python - 寻找最繁忙时段的算法?

c++ 数字的 m 位排列

c++ - 我写的这个计算 NCR 的函数有什么问题吗?

java - 在 Java 中创建记事本

java - 替换字符串中给出的最后一个字符

javascript - 如何将 JSP 中的结果集传递给 Javascript

python - 如何从背包DP矩阵推导出所有解

java - 选择 0/1 背包中的元素,其中两个元素具有相同的 yield |最大化值(value)和最小化重量

java - 在 WildFly 应用服务器上使用 Netbeans 进行增量部署时出错

algorithm - 查找不包括某些对的连续子数组的数量