題目描述
首先要注意,這裡的組合中整數的順序不同代表著不同的順序,所以需要用完全揹包,並且先遍歷揹包容量,再遍歷陣列中的整數。遞推公式之前也遇到過相似的,很好推。
但是按這樣寫了之後會發現有一個樣例溢位了,而且是一種從來沒遇到過的溢位。
看了題解之後發現,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;
}