链接:https://leetcode-cn.com/problems/ones-and-zeroes/
思路:类似于经典01背包,选还是不选问题
经典01背包:
const int M=10000;
int f[M][M];
memset(f,0xcf,sizseof(f));
f[0][0]=0;
for(int i=1;i<=n;i++){
for(int j=0;j<=m;j++)
f[i][j]=f[i-1][j];
for(int j==ve[i];j<=m;j++)
f[i][j]=max(f[i][j],f[i-1][j-ve[i]]+w[i]);
}
return f[n][m];
由于每一个阶段i状态都与上一个阶段的i-1状态有关(这里是直接相等了),用滚动数组优化掉一维,是空间复杂度降低,时间复杂度未变化
const int M=10000;
int f[M];
memset(f,0xcf,sizseof(f));
f[0][0]=0;
for(int i=1;i<=n;i++){
for(int j=m;j>ve[i];j--)//由于正序时,f[j-ve[i]]已经修改,会计算重复,所以倒序
f[j]=max(f[j],f[j-ve[i]]+w[i]);
}
return f[m];
代码:
vector<pair<int,int>>ve;
for(int i=0;i<strs.size();i++){
int am=0,an=0;
for(int j=0;j<strs[i].size();j++)
if(strs[i][j]==‘0‘)am++;
else an++;
ve.push_back({am,an});
}
int len=strs.size();
int f[605][605];
memset(f,0,sizeof(f));//注意初始化问题,如果不确定会到达边界,可以在最后遍历全部找最大的结果作为答案,
for(int i=0;i<len;i++){
int a=ve[i].first;
int b=ve[i].second;
for(int j=m;j>=a;j--)
for(int k=n;k>=b;k--)
f[j][k]=max(f[j][k],f[j-a][k-b]+1);
}
return f[m][n];
原文:https://www.cnblogs.com/abestxun/p/14854574.html