码迷,mamicode.com
首页 > 其他好文 > 详细

89 k数和

时间:2018-07-28 23:25:23      阅读:226      评论:0      收藏:0      [点我收藏+]

标签:rip   代码实现   数组   数据   表示   active   目标   interview   header   

原题网址:https://www.lintcode.com/problem/k-sum/description

描述

给定n个不同的正整数,整数k(k < = n)以及一个目标数字。 

在这n个数里面找出K个数,使得这K个数的和等于目标数字,求问有多少种方案?

您在真实的面试中是否遇到过这个题?  

样例

给出[1,2,3,4],k=2, target=5[1,4] and [2,3]2个符合要求的方案

 

标签

 

LintCode 版权所有
动态规划(DP)
 
 
思路:最开始参照了k数和Ⅱ用递归来做,结果只通过18%的数据就Time Limit Exceeded了。点开标签一看,要用动态规划……一口老血。
好吧,动态规划就动态规划。刚做过背包问题,背包问题中用背包容量作为动态数组一个维度,另一个维度是取0~i个物体,dp值是当前最大容量。而这道题,目标数字相当于背包容量,要作为一个维度,但与背包问题不同的是,这道题是从前i个中取出若干个,又多出一个维度,所以要用三维动态数组,dp值表示当前方案数,大爷的……
dp【i】【j】【t】表示从前i个数中取出j个,这些数的和要等于t,有多少种方案。
状态转移方程:dp【i】【j】【k】=dp【i-1】【j】【t】+dp【i-1】【j-1】【t-A【i】】(当然前提是t>=A【i】);
                    dp[i][j][t]=dp[i-1][j][t];
                    if (t>=A[i])//注意是大于等于;
                    {
                        dp[i][j][t]+=dp[i-1][j-1][t-A[i]];
                    }

意思就是,每个元素都有两种状态,取或者不取:

(1)若不取A[i]这个值,当前方案数等于从前i-1个数中取j个使其和为t的方案数,即dp[i - 1][j][t]。

(2)若取当前值A[i],则当前方案数等于从前i-1个数中取j个使其和为t的方案数再加上考虑A[i]的情况,即dp[i - 1][j - 1][t - A[i]](前提是t - A[i]要大于等于0)。

值得注意的是,如果j为0并且t也为0,则dp【i】【j】【t】=1,即是说从任意集合里拿出0个数使其和为0,这种情况只有一种方案,就是不取任何数。
 
 
AC代码:(注意代码实现的时候对i做了处理,因为第一个数下标是0,或者也可以单独处理i=0的情况)
class Solution {
public:
    /**
     * @param A: An integer array
     * @param k: A positive integer (k <= length(A))
     * @param target: An integer
     * @return: An integer
     */
    int kSum(vector<int> &A, int k, int target) {
        // write your code here
    int size=A.size();
    if (target<0)
    {
        return 0;
    }
    vector<vector<vector<int>>> dp(size+1,vector<vector<int>>(k+1,vector<int>(target+1,0)));
    

    for (int i=0;i<=size;i++)
    {
        for (int j=0;j<=k;j++)
        {
            for (int t=0;t<=target;t++)
            {
                if (j==0&&t==0)//前i个数中取0个和为0只有一种方案,就是不取任何数;
                {
                    dp[i][j][t]=1;
                }
                else if (!(i==0||j==0||t==0))
                {
                    dp[i][j][t]=dp[i-1][j][t];
                    if (t>=A[i-1])//注意是大于等于;
                    {
                        dp[i][j][t]+=dp[i-1][j-1][t-A[i-1]];
                    }
                }
            }
        }
    }
    return dp[size][k][target];
    
    }
};

 

空间优化:
 
 
 
 
 
 
一道题做了好久……各种细节出错,不参照答案写不出来,多维动态数组对我而言还是有一定难度的,哭……
 
参考:
 
 
标记下我最开始的递归代码:
class Solution {
public:
    /**
     * @param A: An integer array
     * @param k: A positive integer (k <= length(A))
     * @param target: An integer
     * @return: An integer
     */
    int kSum(vector<int> &A, int k, int target) {
        // write your code here
    int result=0;
    if (A.empty())
    {
        return result;
    }
    ksum(A,k,target,0,0,0,result);
    return result;
    }
    
    void ksum(vector<int> &A, int k, int target,int sum,int ind,int size,int &result)
{
    if (size==k)
    {
        if (sum==target)
        {
            result++;
        }
        return ;
    }
    if (ind>=A.size())
    {
        return ;
    }
    ksum(A,k,target,sum+A[ind],ind+1,size+1,result);
    ksum(A,k,target,sum,ind+1,size,result);
}
    
};

 

 

 

89 k数和

标签:rip   代码实现   数组   数据   表示   active   目标   interview   header   

原文地址:https://www.cnblogs.com/Tang-tangt/p/9383772.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!