思路
这道题感觉是一个非常好的动态规划的题目,动态规划方程:
d[i][j][target]=d[i−1][j][target]+d[i−1][j−1][target−a[i]]
d
[
i
]
[
j
]
[
t
a
r
g
e
t
]
=
d
[
i
−
1
]
[
j
]
[
t
a
r
g
e
t
]
+
d
[
i
−
1
]
[
j
−
1
]
[
t
a
r
g
e
t
−
a
[
i
]
]
其中 i 表示当前数字的编号,j 表示已选用的数字的数量,target则表示此时达到的总和。
这道题跟最长公共子序列有点类似,都是站在第 i 个数字的角度考虑,考虑第 i 个数字使用和不适用两种情况。如果不使用第 i 个数字达到 target ,则方案数量是 d[i-1][j][target],如果使用了第 i 个数字达到target,则此时的方案数量是 d[i-1][j-1][target-a[i]]。其实数组 d 的第一维并没有实质性的作用,我们可以把它降为二维数组。
代码
public static int kSum(int[] A, int k, int target) {
int[][] num = new int[k+1][target+1];
num[0][0] = 1;
for (int i = 0; i < A.length; i++) {
for (int j = k; j >= 1; j--) {
for (int z = target; z >= A[i]; z--) {
num[j][z] = num[j][z] + num[j-1][z-A[i]];
}
}
}
return num[k][target];
}