没做出来,最后看了解析,看了半天才懂。
我一开始把这个题当成多重背包来做了,因为有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++;
else
oneNum++;
}
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];
}
};