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

效果图专业制作安徽seo优化

效果图专业制作,安徽seo优化,建设官网站,遵义网站建设txwl一和零 https://leetcode.cn/problems/ones-and-zeroes/description/ 题目解析 由递归入手, 就是一颗选和不选的树, 我们很好通过 dfs 来写出递归 题目解析 public class 一和零 {public static int zeros;public static int ones;public int findMaxForm(String[] strs, …

一和零

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

题目解析

由递归入手, 就是一颗选和不选的树, 我们很好通过 dfs 来写出递归

题目解析
public class 一和零 {public static int zeros;public static int ones;public int findMaxForm(String[] strs, int m, int n) {return dfs(strs,m,n,0);}private int dfs(String[] strs, int m, int n, int pos) {if (pos == strs.length) {return 0;}int ans = Integer.MIN_VALUE;// 不选这个ans = dfs(strs,m,n,pos + 1);// 选这个zerosAndOnes(strs[pos],pos);if (m - zeros >= 0 && n - ones >= 0) {ans = Math.max(ans,dfs(strs,m - zeros,n - ones,pos + 1) + 1);}return ans;}private void zerosAndOnes(String str, int pos) {ones = 0;zeros = 0;for (int i = 0; i < str.length(); i++) {if (str.charAt(i) == '1') {ones++;}}zeros = str.length() - ones;}
}

在这里插入图片描述

不出所料地绝对超时了, 我们进行记忆化搜索进行优化, 挂上缓存, 避免重复的递归

记忆化搜索

我们根据变化的三个变量, 构造出一张表, 开始都是 -1, 每次递归如果不是 -1, 说明之前已经进行过一次递归了, 直接拿缓存的值即可
注意 : 数组的下标 m 和 n 需要增加 1, 因为我们是以数组的下标来进行映射的, 所以数组要扩大 + 1

class Solution {public static int zeros;public static int ones;public int findMaxForm(String[] strs, int m, int n) {int[][][] dp = new int[m + 1][n + 1][strs.length];for (int i = 0; i <= m; i++) {for (int j = 0; j <= n; j++) {for (int k = 0; k < strs.length; k++) {dp[i][j][k] = -1;}}}return dfs(strs,m,n,0,dp);}private int dfs(String[] strs, int m, int n, int pos,int[][][] dp) {if (pos == strs.length) {return 0;}if (dp[m][n][pos] != -1) {return dp[m][n][pos];}int ans = Integer.MIN_VALUE;// 不选这个ans = dfs(strs,m,n,pos + 1,dp);// 选这个zerosAndOnes(strs[pos],pos);if (m - zeros >= 0 && n - ones >= 0) {ans = Math.max(ans,dfs(strs,m - zeros,n - ones,pos + 1,dp) + 1);}dp[m][n][pos] = ans;return ans;}private void zerosAndOnes(String str, int pos) {ones = 0;zeros = 0;for (int i = 0; i < str.length(); i++) {if (str.charAt(i) == '1') {ones++;}}zeros = str.length() - ones;}
}

在这里插入图片描述

当我们挂上缓存后已经可以通过了, 这时候我们由自底向上, 考虑如何实现 dp

动态规划

在这里插入图片描述

根据之前的记忆化搜索, 我们可以发现, i 层是严格依赖于 i + 1 层的值, i + 1 层是没有字符串的, 所以全部都置为 0
逻辑直接抄记忆化搜索中的一些关系, 我们只需要处理好边界条件即可

初始化

最上面一层都是 0, 无需进行初始化

填表顺序

层数从上到小还是从下到上都可以, j, k, 由于当前层是依赖于上一层的位置关系, 所以这个 从前往后还是从后往前进行填表都可以

返回值

返回第 0 层, 因为我们是自底向上的, 前 m 个和前 n 个的最大值
所以返回 return dp[0][m][n]

class Solution {public int zeros;public int ones;public int findMaxForm(String[] strs, int m, int n) {int[][][] dp = new int[strs.length + 1][m + 1][n + 1];for (int i = strs.length - 1; i >= 0; i--) {zerosAndOnes(strs[i]);for (int j = 0; j <= m; j++) {for (int k = 0; k <= n; k++) {dp[i][j][k] = dp[i + 1][j][k];if (j - zeros >= 0 && k - ones >= 0) {dp[i][j][k] = Math.max(dp[i][j][k],dp[i + 1][j - zeros][k - ones] + 1);}}}}return dp[0][m][n];}private void zerosAndOnes(String str) {ones = 0;zeros = 0;for (int i = 0; i < str.length(); i++) {if (str.charAt(i) == '1') {ones++;}}zeros = str.length() - ones;}
}
空间压缩

在这里插入图片描述

  1. 因为每一层是相互依赖于每一层的, 所以我们可以使用一个二维表格来进行填写表格, 先把前面的 i 那一层全部删除掉, 我们考虑下一层的依赖关系即可
  2. 根据图片, 我们知道如果在同一层进行填写的话, 依赖的是左上位置的格子, 所以要晚一点覆盖掉这里的格子, 所以我们要从大到小开始填写, 之前的 if 条件来判断防止越界可以直接加到 for 循环中, 防止不必要的遍历, 至于 i 的遍历顺序 从前到后还是从后到前都可以
class Solution {public int zeros;public int ones;public int findMaxForm(String[] strs, int m, int n) {int[][] dp = new int[m + 1][n + 1];for (int i = strs.length - 1; i >= 0; i--) {zerosAndOnes(strs[i]);for (int j = m; j >= zeros; j--) {for (int k = n; k >= ones; k--) {dp[j][k] = Math.max(dp[j][k],dp[j - zeros][k - ones] + 1);}}}return dp[m][n];}private void zerosAndOnes(String str) {ones = 0;zeros = 0;for (int i = 0; i < str.length(); i++) {if (str.charAt(i) == '1') {ones++;}}zeros = str.length() - ones;}
}

盈利计划

题目解析

也是先从递归入手, 我们写出决策树, 每一个 i 都判断选和不选, 直接先通过暴力递归来找到答案

递归
class Solution {public static int mod = 1000000007;public int profitableSchemes(int n, int minProfit, int[] group, int[] profit) {return dfs1(n,minProfit,group,profit,0);}private int dfs1(int n, int minProfit, int[] group, int[] profit, int pos) {// 没人了if (n <= 0) {return minProfit <= 0 ? 1 : 0;}// 没有工作了if (pos == group.length) {return minProfit <= 0 ? 1 : 0;}// 不干这个工作int ans = 0;ans = dfs1(n,minProfit,group,profit,pos + 1) % mod;// 干这个工作if (n >= group[pos]) {ans = (ans +  dfs1(n - group[pos], minProfit - profit[pos], group,profit, pos + 1) % mod) % mod;}return ans;}
}

在这里插入图片描述

不出意料还是超时了, 但是也就差 10 个用例, 说明我们的做法是正确的

记忆化搜索

我们挂上缓存, 需要注意一个细节, 利润会被我们减到负数有可能, 所以我们需要一个比较, 如果变成负数说明利润已经达到了, 我们把它变成 0 , 我们来修改一下代码, 和上一题的整体步骤是差不多的

class Solution {public static int mod = 1000000007;public int profitableSchemes(int n, int minProfit, int[] group, int[] profit) {int[][][] dp = new int[group.length + 1][n + 1][minProfit + 1];for (int i = 0; i <= group.length; i++) {for (int j = 0; j <= n; j++) {for (int k = 0; k <= minProfit; k++) {dp[i][j][k] = -1;}}}return dfs1(n,minProfit,group,profit,0,dp);}private int dfs1(int n, int minProfit, int[] group, int[] profit, int pos,int[][][] dp ) {// 没人了if (n <= 0) {return minProfit <= 0 ? 1 : 0;}// 没有工作了if (pos == group.length) {return minProfit <= 0 ? 1 : 0;}if (dp[pos][n][minProfit] != -1) {return dp[pos][n][minProfit];}// 不干这个工作int ans = 0;ans = dfs1(n,minProfit,group,profit,pos + 1,dp) % mod;// 干这个工作if (n >= group[pos]) {ans = (ans +  dfs1(n - group[pos],Math.max(minProfit - profit[pos],0),group,profit,pos + 1,dp) % mod) % mod;}dp[pos][n][minProfit] = ans;return ans;}
}
动态规划
初始化

最上面一层都是 0, 无需进行初始化
根据图片, 并且每一层都依赖上一层, 所以我们只需要初始化最上面一层即可, 这个和上一题是一样的, 当利润为 0 的时候发现是填入 1, 我们根据记忆化搜索的返回条件可以知道, 所以我们就知道, 最高层的利润为 0 的点填入 1
填表顺序

填表顺序

根据图上画的, 依赖上一层, 从左向右, 从右向左填 j, k都行

返回值

自底向上填写, 最下层满足 dp[0][n][minProfit] 这个可以根据记忆化搜索的返回值得知

class Solution {public static int mod = 1000000007;public int profitableSchemes(int n, int minProfit, int[] group, int[] profit) {int[][][] dp = new int[group.length + 1][n + 1][minProfit + 1];for (int j = 0; j <= n; j++) {dp[group.length][j][0] = 1;}for (int i = group.length - 1; i >= 0; i--) {for (int j = n; j >= 0; j--) {for (int k = minProfit; k >= 0; k--) {dp[i][j][k] = dp[i + 1][j][k] % mod;if (j >= group[i]) {dp[i][j][k] = (dp[i][j][k] + dp[i + 1][j - group[i]][Math.max(k - profit[i],0)] % mod) % mod;}}}}return dp[0][n][minProfit];}
}
空间压缩

在这里插入图片描述

根据上面那张图, 我们用一个二维表来填写, 由于依赖左上方的位置, 所以我们从右下角从右向左, 从上到下进行填写

  1. 先把所有的前缀 i 都删掉
  2. 改一下遍历顺序
  3. 把 if 里的提到 for 循环中, 不提也可以
class Solution {public static int mod = 1000000007;public int profitableSchemes(int n, int minProfit, int[] group, int[] profit) {int[][] dp = new int[n + 1][minProfit + 1];for (int j = 0; j <= n; j++) {dp[j][0] = 1;}for (int i = group.length - 1; i >= 0; i--) {for (int j = n; j >= group[i]; j--) {for (int k = minProfit; k >= 0; k--) {dp[j][k] = (dp[j][k] + dp[j - group[i]][Math.max(k - profit[i],0)] % mod) % mod;}}}return dp[n][minProfit];}
}

此处取模可以去掉一个, 两层是怕溢出, 此题不会溢出, 去掉会快 8 秒左右

http://www.dtcms.com/wzjs/227075.html

相关文章:

  • 企业网站建设资金预算表好网站
  • 中国工商注册网官方岳阳seo公司
  • 公司网站建设多少费用兴田德润在哪里网络销售的好处和意义
  • dw建设网站吉林seo管理平台
  • 网络公司网站建设关键词优化是什么意思?
  • 常熟做网站推广的2019年 2022疫情爆发
  • 类似freenom的免费域名网站seo外链推广员
  • 719y你会回来感谢我的seo词库排行
  • 公司网站建设价格贵吗数据分析师
  • 高端网站建设四川产品软文是什么
  • 石岩网站建设 0755太原seo推广
  • 涟水做网站查找网站
  • 如何让网站收录百度seo公司一路火
  • 上海网站建设公司费用搜索百度指数
  • 江苏网站建设官网什么是seo如何进行seo
  • 简单房地产网站在哪seo网站编辑是做什么的
  • wordpress 网页滚轮翻页信息流优化
  • 利用博客做网站搜索引擎网络排名
  • 重庆智能网站建设设计网络营销就是seo正确吗
  • 毕业设计代做网站 知乎百度贴吧网页版登录入口
  • 做网站前需要做什么准备互联网营销师是什么
  • 国家建设人才网站怎么在腾讯地图上添加自己的店铺
  • 怎样买网站建设做网络推广有哪些平台
  • 响应式网站 做搜索推广缺点重庆好的seo平台
  • 浙江疫情又严重了win10系统优化软件
  • 宇讯网站建设长沙官网seo分析
  • 瀑布流响应式网站模板简述网站建设的流程
  • 北京展示型网站推广普通话奋进新征程手抄报
  • 网站如果实现微信支付吗东莞网站seo推广
  • 星月教你做网站松原头条新闻今日新闻最新