[leetcode]494. 目标和(01 背包dp)

打印 上一主题 下一主题

主题 2085|帖子 2085|积分 6255

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
题目链接
题意

给定n个数的非负数组,每个数都要选,可以选这个数的相反数或者自己,求有多少种方案使得和为target
思路

令s为数组的和,p为数组中选正数的和,p为数组中选负数的和的绝对值,则有                                                   {                                                                                                     p                                              +                                              q                                              =                                              =                                              s                                                                                                                                                  p                                              −                                              q                                              =                                              =                                              ∣                                              t                                              a                                              r                                              g                                              e                                              t                                              ∣                                                                                                       ⇒                                       {                                                                                                     p                                              =                                              s                                              +                                              ∣                                              t                                              a                                              r                                              g                                              e                                              t                                              ∣                                              >                                              >                                              1                                                                                                                                                  q                                              =                                              s                                              −                                              ∣                                              t                                              a                                              r                                              g                                              e                                              t                                              ∣                                              >                                              >                                              1                                                                                                             \begin{cases} p+q==s\\ p-q==|target| \end{cases} \Rightarrow \begin{cases} p=s+|target|>>1\\ q=s-|target|>>1 \end{cases}                     {p+q==sp−q==∣target∣​⇒{p=s+∣target∣>>1q=s−∣target∣>>1​
以是题目转化为了
从n个元素中找出一些数 和为p or q的方案数
就酿成01 背包了
Code

  1. class Solution {
  2. public:
  3.     int findTargetSumWays(vector<int>& nums, int target) {
  4.         int n = nums.size(),s=accumulate(nums.begin(),nums.end(),0)-abs(target);
  5.         int m=s>>1;
  6.         if( s<0 || s%2 ) return 0;
  7.         vector<int>a(n+1);
  8.         for(int i=0;i<n;i++) a[i+1]=nums[i];
  9.         vector dp(n+1,vector<int>(m+1));
  10.         dp[0][0]=1;
  11.         for(int i=1;i<=n;i++){
  12.             for(int j=0;j<=m;j++){
  13.                 if(j<a[i]) {
  14.                     dp[i][j]=dp[i-1][j];
  15.                 }else{
  16.                     dp[i][j]=dp[i-1][j]+dp[i-1][j-a[i]];
  17.                 }
  18.             }
  19.         }
  20.         return dp[n][m];
  21.         
  22.     }
  23. };
复制代码
空间优化

  1. class Solution {
  2. public:
  3.     int findTargetSumWays(vector<int>& nums, int target) {
  4.         int n = nums.size(),s=accumulate(nums.begin(),nums.end(),0)+abs(target);
  5.         if( s<0 || s%2 ) return 0;
  6.         int m=s>>1;
  7.         vector<int>a(n+1);
  8.         for(int i=0;i<n;i++) a[i+1]=nums[i];
  9.         vector<int> dp (m+1);
  10.         dp[0]=1;
  11.         for(int i=1;i<=n;i++){
  12.             for(int j=m;j>=a[i];j--){
  13.                 dp[j]+=dp[j-a[i]];
  14.             }
  15.         }
  16.         return dp[m];
  17.         
  18.     }
  19. };
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

钜形不锈钢水箱

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表