Leetcode 494 Target Sum 动态规划 背包+滚动数据
这是一道水题,作为没有货的水货楼主如是说。
题意:已知一个数组nums {a1,a2,a3,.....,an}(其中0<ai <=1000(1<=k<=n, n<=20))和一个数S
c1a1c2a2c3a3......cnan = S, 其中ci(1<=i<=n)可以在加号和减号之中任选。
求有多少种{c1,c2,c3,...,cn}的排列能使上述等式成立。
例如:
输入:nums is [1, 1, 1, 1, 1], S is 3.
输出 : 5
符合要求5种等式:
-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
但是看完题的你们说,楼主这个题目的难度是中等题呀!
好吧,楼主说错了,它是中等题,但毋庸置疑这是一道动态规划的水题,是一个背包问题,不知道的背包问题的同学请百度下《背包九讲》。
注意:看那个《背包九讲》可能开始会感到生涩难懂,但是前方高能东西都是牛逼的东西。
回归到本题中,乍一看它是一个搜索问题,即搜索出所有可能的解即可,因为n最多为20,搜索一把也能顺利完成,解决也是比较容易的。
但是就没有更好的方法了吗?这时我们注意到0<ai <=1000这个条件,这么小的数值让我们很快联想到了动态规划。
没错,这是一个多阶段的背包问题,其中的难点是负数这么表示。
我们可以将[-max,max]映射到[0,2*max]就解决问题了。
我们现在可以想出以下的状态转移方程:
dp[i][j] = dp[i-][j-a[i]] + dp[i-][j+a[i]]( <= i <= n, < j < * sum(a[i]) + )
即i代表有多少个数,j - sum(a[i])代表每一种算出来的答案,dp[i][j]代表在答案j - sum(a[i])的情况下的c1,c2,c3,...,ci}的排列牌数。很明显当前的状态dp[i][j]是从上一次(i-1)的数加上当前的 a[i]得到的。
这样我们只要开出一个n * (2 * sum(a[i]) + 1)的数组,在O(n * (2 * sum(a[i]) + 1))的时间复杂度下解决这个问题。
那么还可以优化吗?答案是肯定的。
我们从状态转移方程中不难看出,在每一次转移的时候都只用了i-1次的答案和i次的结果,为此我们可以使用滚动数据对它进行优化。
只要我们开出2 * (2 * sum(a[i]) + 1)的数据,这样我们又再次优化了内存。
即我们可以在时间复杂度为O(n * (2 * sum(a[i]) + 1)) 和空间复杂度(2 * (2 * sum(a[i]) + 1)) 的情况下解决该问题。
下面上golang的代码(居然没有golang的语言编辑器,求增加)
func findTargetSumWays(nums []int, S int) int {
mid :=
for _,v := range nums{
mid += v
}
dp := make([][]int, )
for i,_:=range dp{
dp[i] = make([]int, mid + mid + )
}
dp[][mid] =
for i,v := range nums{
for j,_:= range dp[(i + )%]{
dp[(i + )%][j] =
}
for j:=; j <= mid + mid; j++{
if j >= v {
dp[(i+)%][j-v] += dp[i%][j]
}
if j + v <= mid + mid {
dp[(i+)%][j+v] += dp[i%][j]
}
}
}
if S > mid || S < -mid{
return
}
return dp[len(nums)%][S+mid]
}
Leetcode 494 Target Sum 动态规划 背包+滚动数据的更多相关文章
- LN : leetcode 494 Target Sum
lc 494 Target Sum 494 Target Sum You are given a list of non-negative integers, a1, a2, ..., an, and ...
- [LeetCode] 494. Target Sum 目标和
You are given a list of non-negative integers, a1, a2, ..., an, and a target, S. Now you have 2 symb ...
- [Leetcode] DP -- Target Sum
You are given a list of non-negative integers, a1, a2, ..., an, and a target, S. Now you have 2 symb ...
- LC 494. Target Sum
问题描述 You are given a list of non-negative integers, a1, a2, ..., an, and a target, S. Now you have 2 ...
- 【LeetCode】494. Target Sum 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 动态规划 日期 题目地址:https://leetc ...
- 【leetcode】494. Target Sum
题目如下: 解题思路:这题可以用动态规划来做.记dp[i][j] = x,表示使用nums的第0个到第i个之间的所有元素得到数值j有x种方法,那么很容易得到递推关系式,dp[i][j] = dp[i- ...
- 494. Target Sum - Unsolved
https://leetcode.com/problems/target-sum/#/description You are given a list of non-negative integers ...
- 494. Target Sum
You are given a list of non-negative integers, a1, a2, ..., an, and a target, S. Now you have 2 symb ...
- 494. Target Sum 添加标点符号求和
[抄题]: You are given a list of non-negative integers, a1, a2, ..., an, and a target, S. Now you have ...
随机推荐
- css过渡模块和2d转换模块
今天,我们一起来研究一下css3中的过渡模块.2d转换模块和3d转换模块 一.过渡模块transition (一)过度模块的三要素: 1.必须要有属性发生变化 2.必须告诉系统哪个属性需要执行过渡效果 ...
- bzoj3939 【USACO 2015 FEB GOLD 】cow hopscotch
Description 就像人类喜欢玩"跳房子"的游戏,农民约翰的奶牛已经发明了该游戏的一个变种自己玩.由于笨拙的动物体重近一吨打,牛跳房子几乎总是以灾难告终,但这是没有阻止奶牛几 ...
- [内存管理]管理图解v0.1 v0.2 v0.3
内存管理图解v0.1 内存管理图解v0.2 内存管理图解v0.3
- Redis 安装(一)
一.前言 安装 Redis 是开始 Redis 学习之旅的第一步,安装之前先来个简单的介绍. 1. 版本规则 Redis 约定次版本号(即第一个小数点后的数字)为偶数的版本是稳定版,如:2.6,2.8 ...
- 一天精通MongoDB数据库
什么是MongoDB ? MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统. 在高负载的情况下,添加更多的节点,可以保证服务器性能. MongoDB 旨在为WEB应用提供 ...
- WebGIS开源解决方案之矢量数据导入
前几篇介绍了开源WebGIS开发环境的搭建,本篇开始陆续介绍这些软件的使用,WebGIS的开发,首要的问题是解决数据来源,本篇主要介绍矢量数据在开源空间数据库PostgreSQL中的存储.后续篇幅中再 ...
- Scraping_regex
上面链接爬虫只是能将我们所需的网页下载下来,但是,我们没办法得到我们想要的数据.因此,我们只有URL管理器和URL下载器是不足以组成一个完整的网络爬虫的.我们还需要URL解析器,对数据进行提取. 数据 ...
- Docker - 定制镜像
Dockerfile Docker Hub拥有大量高质的官方镜像:可直接使用的服务类镜像.语言应用镜像.基础操作系统镜像等,满足绝大部分需求. 此外,可以通过定制镜像的方式来满足实际使用中的特定需求. ...
- mysql获取当前日期的周一和周日的日期
,,date_format(curdate(),)//获取当前日期 在本周的周一 的日期 ,,date_format(curdate(),)//获取当前日期 在本周的周日 的日期
- j2ee分布式架构 dubbo + springmvc + mybatis + ehcache + redis 分布式架构
介绍 <modules> <!-- jeesz 工具jar --> <module>jeesz-utils</module> ...