zoukankan      html  css  js  c++  java
  • [Leetcode] DP -- Target Sum

    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: 5
    Explanation: 
    
    -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 = 3
    
    There are 5 ways to assign symbols to make the sum of nums be target 3.

    Solution:
     
    1st use  DFS recursive,  like a binary tree;   Go to left (+1) or right (-1); then  when sum is S  go the upper next。
    But it is TLE in python

     

     1     count = 0
     2     def findTargetSumWays(self, nums, S):
     3         def findTargetHelper(nums, index, S):
     4             if index == len(nums):
     5                 if S == 0:
     6                     self.count = self.count + 1
     7                 return
     8              
     9         
    10             findTargetHelper(nums, index+1, S - nums[index])         #+1
    11             findTargetHelper(nums, index+1, S + nums[index])         #-1
    12         
    13         findTargetHelper(nums, 0, S)
    14 
    15         return self.count
    2.   DP
    Refer to the other's idea that I didn't came up with .   
    this problem could be transferred to subset sum problem (similar to knapback problem)
    if there exist a solution,
    P: positive number subset;     N: positive number subset
     then sum(P) - sum(N)  = S;               |P| + |N| = len(nums)
    so  sum(P) + sum(N) + sum(P) - sum(N) =  S + sum(P) + sum(N)
             2*sum(P) = S + sum(nums)
                sum(P) = (S + sum(nums))/2
     the original problem  has been changed to a subset sum problem: :
    Find a subset P of nums such that sum(P) = (target + sum(nums)) / 2
     
     1         def subsetSum(nums, target):
     2             dp = [0]*(target+1)
     3             dp[0] = 1
     4             for num in nums:
     5                 for j in range(target, num-1, -1):
     6                     dp[j] += dp[j-num]
     7                     #print ("dp: ", target, j, dp[j])
     8             return dp[target]
     9             
    10         sumN = sum(nums)
    11         
    12         if sumN < S or (S+sumN) %2 != 0:
    13             return 0
    14         return subsetSum(nums, (S+sumN)>>1)
  • 相关阅读:
    国内顺利使用Google的另类技巧
    Java进程间通信
    Java 多线程(七) 线程间的通信——wait及notify方法
    转:关于copy_to_user()和copy_from_user()的一些用法
    转: pthread_detach()函数
    转:pthread_create()
    转: ubuntu配置NFS,挂载开发板
    转:全志A20 GPIO 总结文档
    转:Linux 内核中的 cdev_alloc和cdev_add
    转:1.1 cdev_init cdev_alloc 使用说明
  • 原文地址:https://www.cnblogs.com/anxin6699/p/7078424.html
Copyright © 2011-2022 走看看