首页 > 其他 > 详细

leetcode每日一题2021-6-6<一和零>(背包)

时间:2021-06-06 10:13:19      阅读:25      评论:0      收藏:0      [点我收藏+]

链接: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];

leetcode每日一题2021-6-6<一和零>(背包)

原文:https://www.cnblogs.com/abestxun/p/14854574.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!