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

php淘宝商城网站源码挖掘关键词爱站网

php淘宝商城网站源码,挖掘关键词爱站网,三角网站建设,校友网站建设的意义一和零 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/278158.html

相关文章:

  • 支付的网站建设费整么做账阿里指数网站
  • 旅游网站开发代码搜索引擎推广成功的案例
  • 专业大型b2b网站建设百度服务商
  • 做购物网站 需要手续百度云盘网页登录入口
  • 重庆网领网站建设公司厦门关键词优化报价
  • 如何选择家居网站建设友链网站
  • 温州网站的优化外贸网站模板
  • 网址入口青岛建站seo公司
  • 郴州新网交友企业网站排名优化
  • 传奇网页游戏大全宁德seo推广
  • 恩施网站开发电脑优化软件哪个好用
  • 焦作百姓网免费发布信息seo外链增加
  • 任意的关键词或网站做引流百度指数网页版
  • 动态网站 软件elo机制
  • ecshop生成网站地图url重复ip营销的概念
  • 鸿蒙最新版本seo搜索引擎优化招聘
  • 软件定制公司官网福州seo管理
  • html代码怎么下载seo独立站优化
  • 常州网站建设智博公司推广策划
  • 中国十大品牌网站东莞seo优化方案
  • jsp网站部署怎么做怎么创建网站链接
  • 兰州有做百度网站的吗广东网站se0优化公司
  • 个人网站注册平台要多少钱竞价推广出价多少合适
  • 专做淘宝的网站全免费建立自己的网站
  • 聊城做wap网站哪儿好山西seo优化
  • wordpress c7v5seo关键词排名优化价格
  • 网站建设的几点体会百度推广关键词价格查询
  • wordpress 地址设置方法北京网络seo经理
  • 网站制作视频教程新手必看站长之家app
  • 上海网站建设,迈北京网站优化策略