zoukankan      html  css  js  c++  java
  • leetcode 494. Target Sum

    leetcode 494. 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.
    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.

    solution

    approach 1 动态规划

    将数组分成两部分,一部分全为正其和为 P,另一部分全为负其和为(-Q)

    P-Q=target
    P+Q+P-Q=target+Q+P
    2P=target+(P+Q)=target+sum(all)
    P=(taget+sum(all))/2
    

    P的值知道了问题就转化为了,从数组中选择若干个数使其和为P,一共有多少种选法?

    令A[n][P]为从第一个到第n个中,选择若干个和为P的选法种数;从而其动态规划的状态转移方程为
    A[n][P]=A[n-1][P]+A[n-1][P-a[n]]
    对于第n个数a[n]来说,如果不选前面的和也为P,那么对于不选a[n],其选法就有A[n-1][p]种,如果选择了a[n]的情况,那么此种选法就有A[n-1][P-a[n]]种选法;
    初始化:当p等于0时,即一个都不选是一种情况,对于第一个数来说,只有P=a[1]时有一种选择的情况
    注意:当一个数字为零是那么可以选择也可以不选择,应该有两种选法

    class Solution {
    public:
    	int findTargetSumWays(vector<int>& nums, int S) {
    
    		int n = nums.size();
    		int sum = 0;
    		for (int i = 0; i < n; i++)
    			sum += nums[i];
    
    		if (S > sum || (sum + S) % 2 != 0)
    			return 0;
    		int cap = (sum + S) / 2;
    
    		int dp[n + 1][sum + 1];
    
    		for (int i = 1; i <= n; i++)
    			for (int j = 0; j <= cap; j++)
    				if (j == 0)
    					if (nums[i - 1] == 0)
    						dp[i][j] = 2;
    					else
    						dp[i][j] = 1;
    				else
    					dp[i][j] = 0;
    		if (nums[0] != 0)
    			dp[1][nums[0]] = 1;
    		else
    			dp[1][nums[0]] = 2;
    		//print("%d",dp[1][1])
    
    		for (int i = 2; i <= n; i++)
    			for (int j = 0; j <= cap; j++)
    			{
    
    				int left = j - nums[i - 1];
    				int tmp = 0;
    				if (left >= 0)
    				{
    					tmp = dp[i - 1][left];
    				}
    				dp[i][j] = dp[i - 1][j] + tmp;
    
    			}
    		return dp[n][cap];
    	}
    };
    

    参考链接

    leetcode

    blogs record our growth
  • 相关阅读:
    如何删除PeopleSoft Process Definition
    你真的了解PeopleSoft中的function和method方法嘛
    PeopleCode事件和方法只用于online界面不能用于组件接口(component interface)
    Lucene.Net 3.0.3如何从TokenStream中获取token对象
    从零开始搭建一个简单的基于webpack的vue开发环境
    Vue路由懒加载
    减少打包组件vue.config.js——Webpack的externals的使用
    axios全局配置及拦截器
    vue-cli中eslint配置
    DDD领域驱动设计基本理论知识总结
  • 原文地址:https://www.cnblogs.com/qwfand/p/12683310.html
Copyright © 2011-2022 走看看