博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
494. Target Sum(转换+dp)
阅读量:4181 次
发布时间:2019-05-26

本文共 1252 字,大约阅读时间需要 4 分钟。

题目:组成目标数有多少种方法?

思路:

举例说明: nums = {1,2,3,4,5}, target=3, 一种可行的方案是+1-2+3-4+5 = 3

该方案中数组元素可以分为两组,一组是数字符号为正(P={1,3,5}),另一组数字符号为负(N={2,4}) 因此: sum(1,3,5) - sum(2,4) = target          sum(1,3,5) - sum(2,4) + sum(1,3,5) + sum(2,4) = target + sum(1,3,5) + sum(2,4)          2sum(1,3,5) = target + sum(1,3,5) + sum(2,4)          2sum(P) = target + sum(nums)          sum(P) = (target + sum(nums)) / 2 由于target和sum(nums)是固定值,因此原始问题转化为求解nums中子集的和等于sum(P)的方案个数问题。

如果 sum(nums) 小于 S或者 (sum(nums) + S) % 2 !=0 表示不能组成目标数,返回0。

应用dp解决子集合问题:

dp[y]+=dp[y-num],表示组成数值y的方案数等于原来组成数值y的方案数 + 组成数值y-num的方案数

例如

dp[8] = dp[8] + dp[8-1] (假设数组为: 1 2 3 4 5)
dp[8] = dp[8] + dp[8-2]
dp[8] = dp[8] + dp[8-3]
dp[8] = dp[8] + dp[8-4]
dp[8] = dp[8] + dp[8-5]

dp代码

for(int num : nums)     for(int y=target;y>=num;y--)        dp[y]+=dp[y-num];

完整代码:

class Solution {public:    int findTargetSumWays(vector
& nums, int S) { int sum = 0; for(int num : nums) sum+=num; if (sum < S || (sum + S) % 2 != 0) return 0; int target = (sum+S)>>1; int dp[target+1]; memset(dp,0,sizeof(dp)); dp[0] = 1; for(int num : nums) for(int y=target;y>=num;y--) dp[y]+=dp[y-num]; return dp[target]; }};

转载地址:http://unrai.baihongyu.com/

你可能感兴趣的文章
《tiny6410裸机程序》第四章:汇编与C混合编程
查看>>
《tiny6410裸机程序》第五章:汇编与C混合编程-LED跑马灯最终说明、myled再次精简
查看>>
《tiny6410裸机程序》第六章:myled通过usb下载至nandflash不能运行
查看>>
《tiny6410裸机程序》第七章:S3C6410外部中断简介
查看>>
《tiny6410裸机程序》第八章:S3C6410外部中断控制寄存器
查看>>
《tiny6410裸机程序》第八章:S3C6410总中断控制寄存器
查看>>
《tiny6410裸机程序》第九章:tiny6410按键控制蜂鸣器程序
查看>>
有关free()函数的一个问题
查看>>
《Android系统学习》之bug定位
查看>>
《Linux内核编程》第七章:USB CORE与USB键鼠驱动
查看>>
《Android系统学习》之JAVA与C混合编程——JNI
查看>>
《C预处理》之#ifndef
查看>>
Android边录边播应用
查看>>
《Linux内核编程》第十三章:Linux对进程内存的二级页式管理
查看>>
ARM协处理器
查看>>
《miniOS分析》前言
查看>>
《Linux内核编程》第十四章:Linux驱动基础
查看>>
Linux平台下ARM-Linux交叉编译工具链
查看>>
Window平台下ADS自带ARMCC编译工具链
查看>>
micro2440/tiny6410使用JLINK直接烧录nand flash
查看>>