【发布时间】:2015-08-04 07:34:41
【问题描述】:
问题:在具有 N 个数字的给定数组上,找到大小为 M(正好是 M 个元素)等于 SUM 的子集。
我正在为这个问题寻找动态规划 (DP) 解决方案。基本上是想了解矩阵填充的方法。我写了下面的程序,但没有添加记忆,因为我仍然想知道如何做到这一点。
#include <stdio.h>
#define SIZE(a) sizeof(a)/sizeof(a[0])
int binary[100];
int a[] = {1, 2, 5, 5, 100};
void show(int* p, int size) {
int j;
for (j = 0; j < size; j++)
if (p[j])
printf("%d\n", a[j]);
}
void subset_sum(int target, int i, int sum, int *a, int size, int K) {
if (sum == target && !K) {
show(binary, size);
} else if (sum < target && i < size) {
binary[i] = 1;
foo(target, i + 1, sum + a[i], a, size, K-1);
binary[i] = 0;
foo(target, i + 1, sum, a, size, K);
}
}
int main() {
int target = 10;
int K = 2;
subset_sum(target, 0, 0, a, SIZE(a), K);
}
下面的递归解决方案有意义吗?
让 DP[SUM][j][k] 求和为 SUM,其中从 0 到 j 个元素中挑选出恰好 K 个元素。
DP[i][j][k] = DP[i][j-1][k] || DP[i-a[j]][j-1][k-1] { input array a[0....j] }
基本情况是:
DP[0][0][0] = DP[0][j][0] = DP[0][0][k] = 1
DP[i][0][0] = DP[i][j][0] = 0
这意味着我们可以考虑这个元素( DP[i-a[j]][j-1][k-1] )或者我们不考虑当前元素(DP[i][j-1][ k])。如果我们考虑当前元素,则 k 减少 1,这减少了需要考虑的元素,当不考虑当前元素时也是如此,即 K 不减少 1。
【问题讨论】:
标签: algorithm recursion dynamic-programming recurrence