In the computer world, use restricted resource you have to generate maximum benefit is what we always want to pursue.
For now, suppose you are a dominator of m 0s
and n 1s
respectively. On the other hand, there is an array with strings consisting of only 0s
and 1s
.
Now your task is to find the maximum number of strings that you can form with given m 0s
and n 1s
. Each 0
and 1
can be used at most once.
Note:
- The given numbers of
0s
and1s
will both not exceed100
- The size of given string array won't exceed
600
.
Example 1:
Input: Array = {"10", "0001", "111001", "1", "0"}, m = 5, n = 3
Output: 4
Explanation: This are totally 4 strings can be formed by the using of 5 0s and 3 1s, which are “10,”0001”,”1”,”0”
Example 2:
Input: Array = {"10", "0", "1"}, m = 1, n = 1
Output: 2
Explanation: You could form "10", but then you'd have nothing left. Better form "0" and "1".
背包问题,容量[m,n],价值为选择的字符串个数。
三维dp空间复杂度可以缩减到2维。有两种方式的dp,第二种dp能存下更多的信息
1.dp[j][k]代表总共可用[j,k]容量时的最大价值,第一种为dp[j][k]=max(dp[j][k],dp[j-c1][k-c2]+1);
2.dp[j][k]代表能刚好得到[j,k]容量时的最大价值(dp[m][n]可能为0);第二种为dp[i+c1][j+c2]=max(dp[i+c1][j+c2],dp[i][j]+1);
(第二种dp[j][k]=max(dp[j][k],dp[j-c1][k-c2]+1)或者这样构造也行)
c1,c2为一个字符串0,1的个数。注意边界情况。
第一种dp。
class Solution {
public int findMaxForm(String[] strs, int m, int n) {
int len=strs.length;
int[][] dp=new int[m+1][n+1];
for(int i=0;i<len;i++){
int c1=0,c2=0;
for(int j=0;j<strs[i].length();j++){
if(strs[i].charAt(j)=='0') c1++;
else c2++;
}
for(int j=m;j>=0;j--){
for(int k=n;k>=0;k--){
if(i==0){
if(j>=c1&&k>=c2){
dp[j][k]=1;
}
}else{
dp[j][k]=dp[j][k];
if(j>=c1&&k>=c2){
dp[j][k]=Math.max(dp[j-c1][k-c2]+1,dp[j][k]);
}
}
}
}
}
return dp[m][n];
}
}
第二种dp.
class Solution {
public int findMaxForm(String[] strs, int m, int n) {
// dp[j+c1][k+c2]=dp[j][k]+1
int len=strs.length;
int[][] dp=new int[m+1][n+1];
for(int i=0;i<len;i++){
int c1=0,c2=0;
for(int j=0;j<strs[i].length();j++){
if(strs[i].charAt(j)=='0') c1++;
else c2++;
}
for(int j=m;j>=0;j--){
for(int k=n;k>=0;k--){
if(dp[j][k]==0&&!(j==0&&k==0)) continue;
if(j+c1<=m&&k+c2<=n){
dp[j+c1][k+c2]=Math.max(dp[j][k]+1,dp[j+c1][k+c2]);
}
}
}
}
int max=0;
for(int j=m;j>=0;j--){
for(int k=n;k>=0;k--){
max=Math.max(max,dp[j][k]);
}
}
return max;
}
}