【力扣】组合总数(另一种整数溢出)
题目描述
首先要注意,这里的组合中整数的顺序不同代表着不同的顺序,所以需要用完全背包,并且先遍历背包容量,再遍历数组中的整数。递推公式之前也遇到过相似的,很好推。
但是按这样写了之后会发现有一个样例溢出了,而且是一种从来没遇到过的溢出。
看了题解之后发现,nums数组和target都不会产生溢出,但是dp数组的元素,也就是组合数的数量可能会在dp[j] += dp[j - nums[i]] 中产生溢出。
但是如果你在递推公式上加了if(dp[j] + dp[j - nums[i]] < INT_MAX),你就会发现溢出仍然没有解决,这种问题之前是看到过的,因为小于号左边的数是非法的,这种情况下正确的判断是:dp[j] < INT_MAX - dp[j - nums[i]],这样就不会溢出了。
代码如下:
#include<bits/stdc++.h>
using namespace std;
int combinationSum4(vector<int>& nums, int target) {
vector<int> dp(target+1, 0);
dp[0] = 1;
int n = nums.size();
for(int j = 0; j <= target; j++){
for(int i = 0; i < n; i++){
if(j - nums[i] >= 0 && dp[j] < INT_MAX - dp[j - nums[i]]){
dp[j] += dp[j - nums[i]];
}
}
// for(int k = 0; k <= target; k++){
// cout<<dp[k]<<" ";
// }
// cout<<endl;
}
return dp[target];
}
int main(){
int n;
cin>>n;
vector<int> nums;
int tmp;
for(int i = 0; i < n; i++){
cin>>tmp;
nums.push_back(tmp);
}
int target;
cin>>target;
cout<<combinationSum4(nums, target);
return 0;
}