【问题标题】:dynamic programming--find target sum ways in an array动态规划——在数组中找到目标求和方式
【发布时间】:2017-06-15 11:48:42
【问题描述】:

在leetcode中遇到一个问题,看了别人用DP的解决方案,但有一点看不懂,希望大家指点一下。

问题是:给定一个只包含正整数的非空数组,找出有多少种方法可以选择其中一些和等于目标 S 的整数。

解决办法是:

int findTargetSumWays(vector<int>& nums, int S) 
{
    int n = nums.size();
    vector<int> dp(S+1, 0);

    dp[0] = 1;
    for(int i=0; i<n; i++)
        for(int j=S; j>=nums[i]; j--)
        //for(int j=nums[i]; j<=S; j++) //why it is wrong?
        {

            dp[j] += dp[j-nums[i]];
        }
    return dp[S];  
}

代码中,第二个循环从S向下计数到nums[i],但是为什么不能从nums[i]向上计数到S呢?我知道如果向上计数,结果会比答案大得多,但我无法弄清楚向上计数的本质问题。

感谢任何帮助!

【问题讨论】:

    标签: c++ algorithm dynamic-programming


    【解决方案1】:

    由于nums[i] 保证为正数,因此:

    dp[j] += dp[j-nums[i]]
    

    根据同一数组中 smaller 索引处的元素值修改数组中 larger 索引处的元素。

    因为j 从高位开始并递减,所以在每次迭代中,保证您需要读取的值(小于 j 的索引)不是您已经覆盖的值(大于 j 的索引)。

    相反,如果您从 j 低开始并递增它,那么您最终会覆盖稍后将在循环中读取的值。然后它们将具有不正确的值并产生错误的答案。

    这类事情是在原地操作数组的算法中非常常见的考虑因素。

    【讨论】:

      【解决方案2】:

      当第二个循环向下计数时,您计算对数组元素求和的所有可能性并获得目标S,其中数组的每个元素只能被取一次。但是,当第二个循环向上计数时,您会计算数组的每个元素都可以被取任意次数的可能性。 所以第二个数字大于或等于第一个数字。

      【讨论】:

        猜你喜欢
        • 2023-03-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多