(01背包型动态规划+三维状态数组)lintcode中等668 · 一和零

题目

描述
在计算机世界中, 由于资源限制, 我们一直想要追求的是产生最大的利益.
现在,假设你分别是 m个 0 和 n个 1 的统治者. 另一方面, 有一个只包含 0 和 1 的字符串构成的数组.
现在你的任务是找到可以由 m个 0 和 n个 1 构成的字符串的最大个数. 每一个 0 和 1 均只能使用一次

数据规模

1.给出的 0 和 1 的个数不会超过 100
2.给出的字符串数组的大小不会超过 600

样例

样例1
输入:
[“10”, “0001”, “111001”, “1”, “0”]
5
3
输出: 4
解释:这里总共有 4 个字符串可以用 5个 0 和 3个 1 来构成, 它们是 “10”, “0001”, “1”, “0”。

样例2
输入:
[“10”, “0001”, “111001”, “1”, “0”]
7
7
输出: 5
解释: 所有字符串都可以由7个 0 和 7个 1 来构成.

分析

解读题意,给定一个字符串数组,数组中的每个字符串都是由0和1组成的,给定两个数字m代表0的个数,n代表1的个数,问花费这些个数字最多可以组成字符串数组中的多少个字符串
看完题目知道这是一道背包型的动态规划,每一个字符串是一种状态,两种情况拿或者不拿,动态规划直接开始两个步骤,先分析最后一步,然后分析转移方程

最后一步

就是最后一个字符串拿或者不拿,但是还有一个条件是限制的,0和1的个数,如果0和1的个数够的情况下才可以拿当前的字符串,这里每一个状态下0和1的个数可能都是不同的,所以我们把0和1也算进状态中,创建一个三维的数组

转移方程

通过上面对最后一步的分析可以得到转移方程,先确定代表状态的数组,f[i][j][k],i代表当前是第几个字符,j代表现在拥有的1的个数,k代表现在拥有的0的个数,f[i][j][k]=max(f[i-1][j]k,f[i-1][j-a[i-1]][k-b[i-1]]|j>=a[i-1]&&k>=b[i-1])

代码部分

初始化

因为要比较当前的0和1的个数和当前字符串中0和1的个数,所以这里我们创建两个数组,分别表示每个字符串中0和1的总个数,

       	int T=strs.size();
		vector<int> cnt0(T);
		vector<int> cnt1(T);
		
		//计算字符串中0和1 
		for(int i=0;i<T;i++)
		{
   
			cnt1[i]=cnt0[i]=0;
			for(int j=0;j<strs[i].size();j++)
			{
   
				if(strs[i][j]=='1')
					++cnt1[i];
				else
					++cnt0[i];
			}
		
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

White boy&

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

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

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

打赏作者

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

抵扣说明:

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

余额充值