问题描述
思路分析
求最值问题,并且需要考虑所有的情况,所以可以用动态规划来写。题中是要选出最大的子集,首先,明确状态,dp[i][j][k]表示考虑第strs[0]到strs[i],0的个数为j,1的个数为k的最大子集。
对应每一个字符串,就有选还是不选的问题。所以状态方程是
dp[i][j][k]=max(dp[i-1][j][k](不选),dp[i-1][j-num0][k-num1]+1(选));
然后还有一个步骤就是初始化的问题,那就是考虑第一个字符串对应的dp数组应该如何写,具体见代码
代码
class Solution {
public:
int findMaxForm(vector<string>& strs, int m, int n) {
int len=strs.size();
int num0=0,num1=0;
vector <vector <vector <int> > > dp(len,vector <vector <int> > (m+1,vector <int>(n+1,0) ));//定义一个三维数组
for(int x=0;x<strs[0].size();x++) {
if(strs[0][x]=='0') num0++;
else num1++;
}//计算strs[0]的相关数据
for(int i=0;i<=m;i++) {
for(int j=0;j<=n;j++) {
if(num0<=i&&num1<=j) dp[0][i][j]=1;
}
}//初始化
for(int i=1;i<=len-1;i++) {
num0=0;
num1=0;
for(int x=0;x<strs[i].size();x++) {
if(strs[i][x]=='0') num0++;
else num1++;
}
for(int j=0;j<=m;j++) {
for(int k=0;k<=n;k++) {
dp[i][j][k]=dp[i-1][j][k];
if(j>=num0&&k>=num1)
dp[i][j][k]=max(dp[i][j][k],dp[i-1][j-num0][k-num1]+1);
}
}
}
return dp[len-1][m][n];
}
};