天天看点

Arithmetic problem | 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 :
Input: nums is [, , , , ], S is 
Output: 
Explanation:

-++++ = 
+-+++ = 
++-++ = 
+++-+ = 
++++- = 

There are  ways to assign symbols to make the sum of nums be target 
           

解题思路:

这题目有一定难度。。。不过由于是数列的数都要使用,那么选了当正数的数出来,剩下的数也就是代表负数了。先合理抽象问题,假设S(r)为在数列里充当正数的数的累计和,S(l)为剩下的数的累计和,那么根据题意容易得到S(r)-S(l)=target。

然而,两个未知数可确定不了解,还有什么可以补充的?那就是数列所有数的和嘛。。。抽象为S(a),意为数列所有数的累计和,得到S(r)+S(l)=S(a)。

两条式子相加,得到S(r)+S(r)=target+S(a)。那么S(r)=(target+S(a))/2。现在的问题完美演变成“从数列里找出n个数的累计和等于(target+S(a))/2”了。由于数列内都为正整数,所以(target+S(a))/2也必须为正数,可得target+S(a)也不会是奇数。

好了,继续抽象这个问题,假设B(n,k)为在前n个数内抽出某些数的累计和为k,从减少规模的情况来看,设n个数最后一个数p一定选中,那么前面部分的数据就需要抽出某些数的累计和等于k-p了,因此得到B(n,k)=B(n-1,k-p)。

至此,低规模数据递推成n规模数据即可。

解题思路代码:

int Method(int *n,int len,int target)
{
    int *matrix=new int[len];
    ZeroMemory(matrix,len);
    int aspt=accumulate(n,n+len)+target;
    if(aspt||len<) return;
    target=aspt;
    matrix];

    for(int i;i<len;++i)
        for(int p=target;p>=n[i];--p)
        {
            matrix[p]+=matrix[p-n[i]];
        }

    int res=matrix[target];
    delete[] matrix;
    return res;
}
           

继续阅读