(01背包型动态规划+三维状态数组)lintcode困难89 · K数之和

题目

描述
给定 n 个不同的正整数,整数 k(k \leq n)(k≤n)以及一个目标数字 target。 
在这 n 个数里面找出 k 个数,使得这 k 个数的和等于目标数字,求问有多少种方案?

样例

样例 1:
输入:
A = [1,2,3,4]
k = 2
target = 5
输出:
2
解释:
1 + 4 = 2 + 3 = 5

样例 2:
输入:
A = [1,2,3,4,5]
k = 3
target = 6
输出:
1
解释:
只有这一种方案。 1 + 2 + 3 = 6

分析

解读题意,给定一个数组A,两个变量k和target,要求从数组A中拿出k个数字他们之和为target,求有多少种方案,每个数字只能拿一次。
判断是一道01背包型动态规划的题,但是多了一个限制条件k,如果没有k的情况下,我们直接就创建一个二维数组,一个代表当前的物品,一个代表背包的最大承重,这里只需要把k加入到状态中即可,还是老方法,先分析最后一步,然后分析转移方程。

1.最后一步

最后一个物品拿还是不拿
情况一不拿
如果最后一个物品不拿,当前方案数最大就是前n-1个物品选k个的最大方案数
情况二拿
最大方案数就是就是前n-1个物品选k-1个的最大方案数
注意选当前物品时背包的最大承重要大于当前的物品(就是说背包可以装的下当前的物品)

2.转移方程

状态f[i][j][k],意思是前i个物品中选前j个,总重量达到k的最大方案数
不拿当前物品时f[i][j][k]=f[i-1][j][k]
拿当前物品时f[i][j][k]=f[i-1][j-1][k-A[i-1]]
拿或者不拿是两个相对的状态,所以总的状态应该将这两种状态加起来
f[i][j][k]=f[i-1][j][k]+f[i-1][j-1][k-A[i-1]]|(j-1>=0&&k>=A[i-1])

代码部分

1.初始化

状态需要0的情况,就是在前0个数字中选…

   	int len=A.size();
    	//前len个数字中选k个和为target,方案数量最多 
    	vector<vector<vector<int> > > f(len+1,
		vector<vector<int> >(k+1,vector<int>(target+1)));

转移方程中,我们需要上一行的数据,所以正常来说我们应该初始化第一行
初始化f[0][0][0],在前0个数字中选0个使总重量为0,这种情况我们什么都不用做就满足,所以这种情况下我们应该初始化为1
当前0个数字的情况,不论是拿1个2个,还是想使总重量达到几,都是达不到的,所以我们应该初始化f[0][0j][0k]的所有值为0

    	f[0][0
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

White boy&

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值