474. 一和零(leetcode)

https://leetcode.cn/problems/ones-and-zeroes/solutions/

多重体积的01背包,关键是需要想到把构造这个最长子集 等价为 往一个背包里塞物品,求能塞最多的物品是多少?且这里有两层体积
这样想就能转化为01背包了,即f[i][j][k]表示在前i个物品中选,j体积不超过m,k体积不超过n的最大价值,这里的价值是物品的数量

class Solution {
    public int findMaxForm(String[] strs, int m, int n) {
        // 思路,把构造最长子集当做放物品到背包中
        // 集合中的元素就是物品,构造的子集就是背包
        // 条件限制不是一般的体积,而是不超过m个0和n个1
        // 这样就转变成了01背包了
        // f[i][j][k] 表示前i个物品中,不超过m个0和n个1的物品最多的选法即j<=m,k<=n,表示的是物品的个数
        // f[0][0~m][0~n]=0;
        // f[1~i][0][0]=0;
        // 初值:f[1][合法取值][合法取值] = 1 , 若不合法,则为0
        // 这里定义num()这个函数,即在目标容器中有多少个目标值
        // f[i][j][k] = max(f[i-1][j][k],f[i-1][j-num(strs[i],0) ][k-num(strs[i],1)] + 1 )



        int N = 110;
        int[][][] f=new int[610][N][N];
        for(int i=1;i<=strs.length;i++)
        {
            // 获取当前物品的体积
            int[] zerosOnes = getZerosOnes(strs[i - 1]);
            int zeros = zerosOnes[0], ones = zerosOnes[1];
            for(int j=0;j<=m;j++)
                for(int k=0;k<=n;k++)
                {
                    if(j>=zeros && k>=ones)
                        f[i][j][k]=Math.max(f[i-1][j][k],f[i-1][j-zeros][k-ones] + 1 );
                    else f[i][j][k]=f[i-1][j][k];
                }
        }

        return f[strs.length][m][n];
        
    }

    public int[] getZerosOnes(String str) {
        int[] zerosOnes = new int[2];
        int length = str.length();
        for (int i = 0; i < length; i++) {
            zerosOnes[str.charAt(i) - '0']++;
        }
        return zerosOnes;
    }

}
class Solution {
    public int findMaxForm(String[] strs, int m, int n) {
        // 思路,把构造最长子集当做放物品到背包中
        // 集合中的元素就是物品,构造的子集就是背包
        // 条件限制不是一般的体积,而是不超过m个0和n个1
        // 这样就转变成了01背包了
        // f[i][j][k] 表示前i个物品中,不超过m个0和n个1的物品最多的选法即j<=m,k<=n,表示的是物品的个数
        // f[0][0~m][0~n]=0;
        // f[1~i][0][0]=0;
        // 初值:f[1][合法取值][合法取值] = 1 , 若不合法,则为0
        // 这里定义num()这个函数,即在目标容器中有多少个目标值
        // f[i][j][k] = max(f[i-1][j][k],f[i-1][j-num(strs[i],0) ][k-num(strs[i],1)] + 1 )



        int N = 110;
        int[][] f=new int[N][N];
        for(int i=1;i<=strs.length;i++)
        {
            // 获取当前物品的体积
            int[] zerosOnes = getZerosOnes(strs[i - 1]);
            int zeros = zerosOnes[0], ones = zerosOnes[1];
            for(int j=m;j>=0;j--)
                for(int k=n;k>=0;k--)
                {
                    if(j>=zeros && k>=ones)
                        f[j][k]=Math.max(f[j][k],f[j-zeros][k-ones] + 1 );
                    else f[j][k]=f[j][k];
                }
        }

        return f[m][n];
        
    }

    public int[] getZerosOnes(String str) {
        int[] zerosOnes = new int[2];
        int length = str.length();
        for (int i = 0; i < length; i++) {
            zerosOnes[str.charAt(i) - '0']++;
        }
        return zerosOnes;
    }

}

 

posted @   风乐  阅读(15)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示