马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
题目链接
题意
给定n个数的非负数组,每个数都要选,可以选这个数的相反数或者自己,求有多少种方案使得和为target
思路
令s为数组的和,p为数组中选正数的和,p为数组中选负数的和的绝对值,则有 { p + q = = s p − q = = ∣ t a r g e t ∣ ⇒ { p = s + ∣ t a r g e t ∣ > > 1 q = s − ∣ t a r g e t ∣ > > 1 \begin{cases} p+q==s\\ p-q==|target| \end{cases} \Rightarrow \begin{cases} p=s+|target|>>1\\ q=s-|target|>>1 \end{cases} {p+q==sp−q==∣target∣⇒{p=s+∣target∣>>1q=s−∣target∣>>1
以是题目转化为了
从n个元素中找出一些数 和为p or q的方案数
就酿成01 背包了
Code
- class Solution {
- public:
- int findTargetSumWays(vector<int>& nums, int target) {
- int n = nums.size(),s=accumulate(nums.begin(),nums.end(),0)-abs(target);
- int m=s>>1;
- if( s<0 || s%2 ) return 0;
- vector<int>a(n+1);
- for(int i=0;i<n;i++) a[i+1]=nums[i];
- vector dp(n+1,vector<int>(m+1));
- dp[0][0]=1;
- for(int i=1;i<=n;i++){
- for(int j=0;j<=m;j++){
- if(j<a[i]) {
- dp[i][j]=dp[i-1][j];
- }else{
- dp[i][j]=dp[i-1][j]+dp[i-1][j-a[i]];
- }
- }
- }
- return dp[n][m];
-
- }
- };
复制代码 空间优化
- class Solution {
- public:
- int findTargetSumWays(vector<int>& nums, int target) {
- int n = nums.size(),s=accumulate(nums.begin(),nums.end(),0)+abs(target);
- if( s<0 || s%2 ) return 0;
- int m=s>>1;
- vector<int>a(n+1);
- for(int i=0;i<n;i++) a[i+1]=nums[i];
- vector<int> dp (m+1);
- dp[0]=1;
- for(int i=1;i<=n;i++){
- for(int j=m;j>=a[i];j--){
- dp[j]+=dp[j-a[i]];
- }
- }
- return dp[m];
-
- }
- };
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |