题目
描述
在计算机世界中, 由于资源限制, 我们一直想要追求的是产生最大的利益.
现在,假设你分别是 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];
}