給定乙個非負整數陣列,a1, a2, …, an, 和乙個目標數,s。現在你有兩個符號 + 和 -。對於陣列中的任意乙個整數,你都可以從 + 或 -中選擇乙個符號新增在前面。
返回可以使最終陣列和為目標數 s 的所有新增符號的方法數。
這個題的選擇就兩種,做加法或者做減法(不能選擇不加),所以其實是乙個動態規劃.又因為需要達到s,所以用j來表示狀態,就是乙個01揹包了.
dp[i][j]中i表示0到i的陣列中可選擇的,j表示加起來到j,.dp[i][j]表示此時的方法數.
dp[i][j]=dp[i-1][j-num[i]]+dp[i-1][j+num[i]];但是必須選的話初始狀態不好確定,所以可以轉換為傳統的看選不選的問題
我們把nums劃分為兩個子集a和b,分別代表分配+的數字和分配-的數字,則可以得出a-b=s a=s+b 2a=s+a+b a=s/2+(a+b)/2
則問題可以轉換為有幾個a使得a中元素和為x=(s+sum(nums))/2 這也就是乙個子集劃分問題,也就轉換為乙個揹包問題,求有幾種方法來裝滿乙個目標和為x的揹包dp[i][j]=max(dp[i-1][j],dp[i-1][j-num[i]+val[i]])
class
solution
if(s(s+s)%2
==1)return0;
s=(s+s)/2
;int
dp=
newint
[nums.length+1]
[s+1];
for(
int i=
0;i<=nums.length;i++
)for
(int i=
1;i<=nums.length;i++)}
return dp[nums.length]
[s];
}}
狀態壓縮意味著將二維陣列壓縮成一維陣列,其實就是投影,想象把所有的值全部壓縮到一根道上。初始值這麼壓縮,然後狀態變的時候也要這麼壓縮 但dp[i][j]用到dp[i-1][j] dp[i-1][j-num[i-1]]這就需要前一行的前面的值,所以從後遍歷即可。
class
solution
if(s(s+s)%2
==1)return0;
s=(s+s)/2
;int
dp=
newint
[s+1];
dp[0]
=1;for
(int i=
1;i<=nums.length;i++)}
return dp[s];}
}
0 1揹包 LeetCode 494 目標和
494.目標和 給定乙個非負整數陣列,a1,a2,an,和乙個目標數,s。現在你有兩個符號 和 對於陣列中的任意乙個整數,你都可以從 或 中選擇乙個符號新增在前面。返回可以使最終陣列和為目標數 s 的所有新增符號的方法數。示例 1 輸入 nums 1,1,1,1,1 s 3 輸出 5 解釋 1 1 ...
leetcode 494目標和 揹包dp
class solution def findtargetsumways self,nums,s int dp i j means solutionnums n len nums sum max sum nums sum min sum max dp dp 0for in range s 1 for...
又見01揹包(01揹包題目3)
時間限制 1000 ms 記憶體限制 65535 kb 難度 3 描述 有n個重量和價值分別為wi 和 vi 的 物品,從這些物品中選擇總重量不超過 w 的物品,求所有挑選方案中物品價值總和的最大值。1 n 100 1 wi 10 7 1 vi 100 1 w 10 9 輸入多組測試資料。每組測試資...