【力扣】組合總數(另一種整數溢位)

SaTsuki26681534發表於2024-03-25

題目描述

image
首先要注意,這裡的組合中整數的順序不同代表著不同的順序,所以需要用完全揹包,並且先遍歷揹包容量,再遍歷陣列中的整數。遞推公式之前也遇到過相似的,很好推。

但是按這樣寫了之後會發現有一個樣例溢位了,而且是一種從來沒遇到過的溢位。
看了題解之後發現,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;
}

相關文章