没做出来,最后看了解析,看了半天才懂。
我一开始把这个题当成多重背包来做了,因为有0和1两个参数需要考虑,但是中间很多情况不知道怎么处理。后面看了解析才知道这是个01背包问题,0和1都是一个物品上的属性,只要考虑该物体的放入与否就行。
这个题的处理点在于把背包的容量变成二维,初始的dp[i]表示容量为i的背包可放入的最大物品数,现在d[i][j]为最多有i个0和j个1的str最大子集个数
状态转移方程:dp[i][j] = max(dp[i][j], dp[i - zeroNum][j - oneNum] + 1);
dp[i - zeroNum][j - oneNum]就是上一个str数组的dp状态
该题的转移方程:
初始的转移方程:
dp[j]=max(dp[j],dp[j-value[i]]+valve[i]);
可以发现其实[i][j]就是[j],只是二维表示了,而起初的外层循环为遍历物品,这里省去了,因为每次都是只涉及不变和+1,该题中两层遍历都是对背包容量的遍历
class Solution {
public:int findMaxForm(vector<string>& strs, int m, int n) {vector<vector<int>> dp(m+1,vector<int>(n+1,0));for(string str:strs){int zeroNum=0,oneNum=0;for(char c:str){if(c=='0') zeroNum++;elseoneNum++;}for(int i=m;i>=zeroNum;i--)for(int j=n;j>=oneNum;j--)dp[i][j]=max(dp[i][j],dp[i-zeroNum][j-oneNum]+1);}return dp[m][n];}
};