大概题意为:给定一个正整数集合S,与一个正整数target。求从集合S中取出若干个数,可重复使用,使得它们的和为target的种类数。注意,不同的排序也是不同的种类。
观察一下测试样例,这样更显的直观:
其中(1, 1, 2),(1, 2, 1) 和(2, 1, 1) 是不同的方案。
其实这道题很容易就能写出递推公式。考了一个目标数target,假设我们取了数x,则问题就转化为求目标数为target - x的种类数,如果我们知道target - x 的种类数,则我们就知道了取了x 的目标数为target的种类数。
因此有递推公式:
d(target)即为所求。设目标数为m,集合大小为m。则时间复杂度为O(nm) 。具体代码如下:
const int maxn = 100000 + 50 ;
int d[maxn] ;
class Solution {
public:
int combinationSum4(vector<int>& nums, int target) {
memset(d, 0, sizeof(d)) ;
d[0] = 1 ;
int s = nums.size() ;
if (s == 0) return 0 ;
for (int i=1; i<=target; i++) {
for (int j=0; j<s; j++) {
if (i >= nums[j]) d[i] += d[i-nums[j]] ;
}
}
return d[target] ;
}
};