【力扣】组合总数(另一种整数溢出)

题目描述

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;
}
posted @ 2024-03-25 00:23  SaTsuki26681534  阅读(3)  评论(0编辑  收藏  举报