Target Sum

本週選做的題目也是關於動態規劃的應用,Target Sum,題目要求如下:

You are given a list of non-negative integers, a1, a2, ..., an, and a target, S. Now you have 2 symbols + and -. For each integer, you should choose one from + and - as its new symbol.

Find out how many ways to assign symbols to make sum of integers equal to target S.

Example 1:

Input: nums is [1, 1, 1, 1, 1], S is 3. 
Output: 5
Explanation: 

-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

There are 5 ways to assign symbols to make the sum of nums be target 3.
我們可以以另一種方式理解這道題目,將數分為正數(P)與負數(N),將P+N=target,所以我們有

sum(P) - sum(N) = target
sum(P) + sum(N) + sum(P) - sum(N) = target + sum(P) + sum(N)
2 * sum(P) = target + sum(nums)
因此就變成尋找nums的子集P,並且有sum(P) = (sum(nums) + target) / 2,sum(nums) + target必須是偶數,在程序中多加一句半段語句sum < s || (s + sum) % 2 ? 0 : subsetSum(nums, (s + sum) / 2);


以下為我參考相關動態規劃寫法並總結出來的程序

int subsetSum(vector<int>& nums, int s) 
{
    int dp[s + 1] = { 0 };
    dp[0] = 1;
    for (int j = 0; j < nums.size(); j++)
    {
    int n = nums[j];
    for (int i = s; i >= n; i--)
    {
    dp[i] += dp[i - n];
    //cout << "dp " << i << ": " << dp[i]<<endl;
}
//cout << endl;
            

    return dp[s];
}


int findTargetSumWays(vector<int>& nums, int s) 
{
    int sum = accumulate(nums.begin(), nums.end(), 0);
    return sum < s || (s + sum) % 2 ? 0 : subsetSum(nums, (s + sum) / 2); 




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章