[DFS][dp]leetcode494:目标和(medium)

题目:
[DFS][dp]leetcode494:目标和(medium)_第1张图片

解题思路:

  • 解法1:动态规划
  • 1)每个元素可看作一个物品,+1表示将此物品取出,-1表示将此物品放回
  • 2)sum表示将所有物品全部取出,sum+S表示有些物品取出两次,有些物品取出后又放回,这样就是表示+1的有两次,除以2就是+1的取出一次。
  • 3)本题本质和01背包一样的,利用动态规划解题

  • 解法2:深度优先优先搜索
  • 使用DFS穷举所有可能的情况,暴搜+剪枝

代码如下:

class Solution {
public:
 	/*解法1:利用dp*/
    int findTargetSumWays_1(vector<int>& nums, int S) {
        int sum=0;
        for(auto num:nums)//求总和
            sum+=num;
        if(sum<S||(sum+S)%2==1)return 0;
        sum=(sum+S)/2;
        vector<int> dp(sum+1,0);//dp[i]表示重量i的情况数
        dp[0]=1;
        for(auto num:nums)//进行动态规划
            for(int i=sum;i>=num;--i)
                 dp[i] += dp[i-num];
        return dp[sum];
    }
    
    /*解法2:深度优先搜索+剪枝*/
    int findTargetSumWays(vector<int>& nums, int S) {
    	int result=0;
        DFS(nums,0,S,0,result);
        return result;   
    }
    
    void DFS(vector<int>& nums,int index,int S,int sum,int& result)
    {
        int size=nums.size();
        if(size==index)//到达尾部,检查是否等于S
        {   
            if(sum==S)
                result+=1;
            return;
        }
        else if(index<size)
        {
            //穷举正负号
            DFS(nums,index+1,S,sum-nums[index],result);
            DFS(nums,index+1,S,sum+nums[index],result);
        }
    }
};

你可能感兴趣的:(leetcode刷题,#,动态规划,#,DFS)