【算法日志】动态规划刷题:01背包问题(day36)

代码随想录刷题60Day


前言

今天主要讨论背包问题中的01背包问题,这类问题的难点在于怎样对问题进行数学建模。一旦思考好问题的解决方式,剩下的步骤就比较简单了。


分割等和子集

【算法日志】动态规划刷题:01背包问题(day36)_第1张图片

本题可采用暴力回溯,但复杂度比较高,所以采取动态规划会更好。但难点在于怎样将该问题转化成能够采取动规策略的01背包问题。

	bool canPartition(vector& nums) 
	{
		if (nums.size() == 1)return false;
		int sum = 0;
		int size = nums.size();
		sort(nums.begin(), nums.end());
		for (int i = 0; i < size; ++i)
			sum += nums[i];
		if (sum % 2)return false;
		int target = sum / 2;
		vector dp(target + 1, 0);
		for (int i = 0; i < size; ++i)
		{
			for (int j = target; j >= nums[i]; --j)
				dp[j] = max(dp[j], dp[j - nums[i]] + nums[i]);
		}
		if (dp[target] == target)return true;
		return false;
	}

最后一块石头的重量

【算法日志】动态规划刷题:01背包问题(day36)_第2张图片

int lastStoneWeightII(vector& stones) 
	{
		int sum = 0;
		const int size = stones.size();
		for (int i = 0; i < size; ++i)
			sum += stones[i];
		int target = sum / 2;
		vector dp(target + 1, 0);
		for (int i = 0; i < size; ++i)
		{
			for (int j = target; j >= stones[i]; --j)
				dp[j] = max(dp[j], dp[j - stones[i]] + stones[i]);
		}
		return sum - 2 * dp[target];
	}

你可能感兴趣的:(算法,动态规划,leetcode)