当前位置: 首页 > news >正文

力扣刷题474. 一和零

474. 一和零 - 力扣(LeetCode)

这一道题主要是把实际问题抽象为背包问题,对于每一个字符串的价值都是1,每一个字符串的体积由两部分组成,0和1的大小,所以判断时需要同时满足0和1的大小同时小于给定的01大小(背包容量)。

我们先求出每一个字符串的体积(0和1的个数),第一层循环即为遍历所有的字符串,内循环为双层循环,因为要同时满足两个条件,k为当前的字符串,i为背包0的容量,j为背包1的容量。可以推出递推公式为:

dp[k][i][j] = max( dp[k - 1][ i ][ j ] , dp[k - 1][ i - cnt[ k - 1][ 0 ] ][ j - cnt[ k - 1][ 1 ]  +1  )


public class Main {

	public static void main(String[] args) {
		String[] strs = { "10", "0001", "111001", "1", "0" };
		int m = 5;// m个0
		int n = 3;// n个1
		int a = findMaxForm(strs, m, n);
		System.out.println(a);

	}

	public static int findMaxForm(String[] strs, int m, int n) {
		int len = strs.length;
		int[][] cnt = new int[len][2];
		for (int i = 0; i < len; i++) {
			String str = strs[i];
			int ZeroCount = 0;
			int OneCount = 0;
			for (char c : str.toCharArray()) {
				if (c == '0')
					ZeroCount++;
				else
					OneCount++;
			}
			cnt[i][0] = ZeroCount;
	    	cnt[i][1] = OneCount;
		}

		int[][][] dp = new int[len + 1][m + 1][n + 1];
		for (int k = 1; k <= len; k++) {
			int zero = cnt[k - 1][0];
			int one = cnt[k - 1][1];

			for (int i = 0; i <= m; i++) {
				for (int j = 0; j <= n; j++) {
					// 不选
					int a = dp[k - 1][i][j];
					// 选
					int b = (i >= zero && j >= one) ? dp[k - 1][i - zero][j - one] + 1 : 0;
					dp[k][i][j] = Math.max(a, b);
				}
			}
		}
		return dp[len][m][n];
	}

}

相关文章:

  • 强化学习课程:stanford_cs234 学习笔记(2)introduction to RL
  • UDP协议
  • 随机2级域名引导页HTML源码
  • 【docker】docker应用举例
  • 1.两数之和(Java)
  • 北斗储罐位移监测系统解决方案
  • java倒序题变形题重温
  • 在Ubuntu中固定USB设备的串口号
  • QML中的附加属性和附加信号处理程序
  • [特殊字符]《Curve DAO 系统学习目录》
  • Java 面向对象编程中 static 的深度剖析与实践
  • jdbc入门
  • Java 日志技术全面解析与实践教程
  • 多线程—线程安全集合类与死锁
  • 3.23周赛补题
  • C#:第一性原理理解日志(log)
  • 从零实现Json-Rpc框架】- 项目实现 - 基于Dispatcher模块的RPC框架
  • `git commit --amend` 详解:修改提交记录的正确方式
  • Content-Type设置内容类型
  • React受控表单绑定