版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/roufoo/article/details/83211335
这题类似完全背包。
代码如下:
class Solution {
public:
/**
* @param nums: an integer array and all positive numbers, no duplicates
* @param target: An integer
* @return: An integer
*/
int backPackVI(vector<int> &nums, int target) {
int n = nums.size();
vector<int> dp(target + 1, 0); //dp[i] is the number of possible combinations that add up to i
dp[0] = 1;
for (int j = 0; j <= target; ++j) {
for (int i = 0; i < n; ++i) {
if (j >= nums[i])
dp[j] += dp[j - nums[i]];
// cout<<"i="<<i<<" j="<<j<<" dp="<<dp[j]<<endl;
}
}
return dp[target];
}
};
注意:
1)循环i和循环j不能互换(即不能先i循环,再j循环)。否则出错。
以nums=[1,2,4]和target=4为例,
上面的打印信息为:
i=0 j=0 dp=1
i=1 j=0 dp=1
i=2 j=0 dp=1
i=0 j=1 dp=1
i=1 j=1 dp=1
i=2 j=1 dp=1
i=0 j=2 dp=1
i=1 j=2 dp=2
i=2 j=2 dp=2
i=0 j=3 dp=2
i=1 j=3 dp=3
i=2 j=3 dp=3
i=0 j=4 dp=3
i=1 j=4 dp=5
i=2 j=4 dp=6
但如果我们把循环i和循环j的顺序倒过来,即
for (int i = 0; i < n; ++i) {
for (int j = nums[i]; j <= target; ++j) {
dp[j] += dp[j - nums[i]];
//cout<<"i = "<<i<<" j="<<j<<" dp="<<dp[j]<<endl;
}
}
则打印信息为:
i=0 j=1 dp=1
i=0 j=2 dp=1
i=0 j=3 dp=1
i=0 j=4 dp=1
i=1 j=2 dp=2
i=1 j=3 dp=2
i=1 j=4 dp=3
i=2 j=4 dp=4