zoukankan      html  css  js  c++  java
  • 算法——利用数组内所有元素进行加或者减以达到目标和

    给定一个非负整数数组,a1, a2, …, an, 和一个目标数,S。现在你有两个符号 + 和 -。对于数组中的任意一个整数,你都可以从 + 或 -中选择一个符号添加在前面。
    返回可以使最终数组和为目标数 S 的所有添加符号的方法数。
    leetcode

    解题思路:

    • 首先想到的是暴力深搜,枚举每一种做法,这样时间复杂度是n方的,也没有什么意义。
    • 可以采用动态规划的思想。设负数和为y,正数和为x,则有 x + y = S,还有x - y = sum,sum是数组中所有元素的累加。这样可以得到 x = (S + sum) / 2,于是将问题转化为了一个01背包问题。
    class Solution {
        public int findTargetSumWays(int[] nums, int s) {
            int sum = 0;
    
            for(int n : nums) sum += n;
    
    		// 因为不存在小数,正数和一定是偶数,所以,如果是奇数就直接返回0
            if((sum + s) % 2 == 1) return 0;
            
            // 全部都为正数还每目标值大,那就没必要算了
            if(s > sum) return 0;
    
            int len = (sum + s) / 2;
            int[] f = new int[len + 1];
            f[0] = 1;
    
    		// 01背包,先枚举物品,再从高到底枚举和
            for(int n : nums) {
                for(int i = len; i >= n; i--) {
                    f[i] += f[i - n];
                }
            }
    
            return f[len];
        }
    }
    
  • 相关阅读:
    [bzoj4197][Noi2015]寿司晚宴
    [bzoj3531][Sdoi2014]旅行
    [洛谷P1430]序列取数
    [洛谷P2044][NOI2012]随机数生成器
    [洛谷P2839][国家集训队]middle
    [洛谷P3937]Changing
    [bzoj3532][Sdoi2014]Lis
    [洛谷P2590][ZJOI2008]树的统计
    [洛谷P4311]士兵占领
    [洛谷P1879][USACO06NOV]玉米田Corn Fields
  • 原文地址:https://www.cnblogs.com/lippon/p/14117612.html
Copyright © 2011-2022 走看看