LeetCode
来源:互联网 发布:36氪php招聘 编辑:程序博客网 时间:2024/05/18 06:47
You are given a list of non-negative integers, a1, a2, ..., an, and a target, S. Now you have 2 symbols +
and -
. For each integer, you should choose one from +
and -
as its new symbol.
Find out how many ways to assign symbols to make sum of integers equal to target S.
Example 1:
Input: nums is [1, 1, 1, 1, 1], S is 3. Output: 5Explanation: -1+1+1+1+1 = 3+1-1+1+1+1 = 3+1+1-1+1+1 = 3+1+1+1-1+1 = 3+1+1+1+1-1 = 3There are 5 ways to assign symbols to make the sum of nums be target 3.
Note:
- The length of the given array is positive and will not exceed 20.
- The sum of elements in the given array will not exceed 1000.
- Your output answer is guaranteed to be fitted in a 32-bit integer.
一碰到dp,就很容易懵。写写正解思路吧,参考 http://blog.csdn.net/mine_song/article/details/70216562
【问题分析】
1、该问题求解数组中数字只和等于目标值的方案个数,每个数字的符号可以为正或负(减整数等于加负数)。
2、该问题和矩阵链乘很相似,是典型的动态规划问题
3、举例说明: nums = {1,2,3,4,5}, target=3, 一种可行的方案是+1-2+3-4+5 = 3
该方案中数组元素可以分为两组,一组是数字符号为正(P={1,3,5}),另一组数字符号为负(N={2,4})
因此: sum(1,3,5) - sum(2,4) = target
sum(1,3,5) - sum(2,4) + sum(1,3,5) + sum(2,4) = target + sum(1,3,5) + sum(2,4)
2sum(1,3,5) = target + sum(1,3,5) + sum(2,4)
2sum(P) = target + sum(nums)
sum(P) = (target + sum(nums)) / 2
由于target和sum(nums)是固定值,因此原始问题转化为求解nums中子集的和等于sum(P)的方案个数问题
4、求解nums中子集和为sum(P)的方案个数(nums中所有元素都是非负)
此处就是一个经典的0/1背包了,详细过程省略
class Solution {public: int findTargetSumWays(vector<int>& nums, int S) { int sum = 0; for (int i = 0; i < nums.size(); ++i) sum += nums[i]; if (sum < S || (sum + S) % 2 == 1) return 0; return solve(nums, (sum + S) / 2); } int solve(vector<int> nums, int s) { vector<int> ans(s+1, 0); ans[0] = 1; for (int i = 0; i < nums.size(); ++i) { for (int j = s; j >= nums[i]; --j) { ans[j] += ans[j-nums[i]]; } } return ans[s]; }};
- leetcode
- [leetcode]
- LeetCode
- leetcode
- leetcode
- leetcode:
- leetcode:
- LeetCode
- leetcode
- LEETCODE
- leetcode
- leetCode
- leetcode
- [leetcode]
- LeetCode
- leetcode
- leetcode:
- leetcode
- 左式堆
- linux下2>&1
- ORACLE从另外两张表中查询数据插入新表,添加id自增触发器
- 数据仓库建设快速入门---事实表和维度表的设计
- ubuntu12.04 64位下安装hackrf
- LeetCode
- QString与char*互转
- CDHtmlDialog中阻止某页面的显示
- ngx_rtmp_notify_module.c 源码分析
- c#打包下载
- 【面经笔记】析构函数一般写成虚函数的原因
- 洛谷 P1196 银河英雄传说
- 安卓学习笔记--- Android 6.0运行时权限的申请使用及EasyPermissions的使用
- SpingMVC中的@ModelAttribute详解