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

手机网站设计只选亿企邦虚拟主机与网站建设

手机网站设计只选亿企邦,虚拟主机与网站建设,微信保修网站开发源代码,深圳建设网站算法拾遗二十七之暴力递归到动态规划七题目一【数组累加和最小的】题目二什么暴力递归可以继续优化暴力递归和动态规划的关系面试题和动态规划的关系如何找到某个问题的动态规划方式面试中设计暴力递归的原则知道了暴力递归的原则 然后设计常见的四种尝试模型如何分析有没有重复…

算法拾遗二十七之暴力递归到动态规划七

      • 题目一【数组累加和最小的】
      • 题目二
        • 什么暴力递归可以继续优化
        • 暴力递归和动态规划的关系
        • 面试题和动态规划的关系
        • 如何找到某个问题的动态规划方式
        • 面试中设计暴力递归的原则
        • 知道了暴力递归的原则 然后设计
        • 常见的四种尝试模型
        • 如何分析有没有重复解
        • 暴力递归到动态规划的套路
        • 动态规划的进一步优化
      • N皇后问题

题目一【数组累加和最小的】

在这里插入图片描述
找较小的集合最接近两个集合总和的一半:

	public static int right(int[] arr) {if (arr == null || arr.length < 2) {return 0;}//统计所有数的累加和int sum = 0;for (int num : arr) {sum += num;}return process(arr, 0, sum / 2);}// arr[i...]从i位置出发及其后面的数可以自由选择,// 请返回累加和尽量接近rest,但不能超过rest的情况下,最接近的累加和是多少?public static int process(int[] arr, int i, int rest) {if (i == arr.length) {return 0;} else { // 还有数,arr[i]这个数// 可能性1,不使用arr[i],直接index+1,rest不变int p1 = process(arr, i + 1, rest);// 可能性2,要使用arr[i]int p2 = 0;if (arr[i] <= rest) {p2 = arr[i] + process(arr, i + 1, rest - arr[i]);}return Math.max(p1, p2);}}

改dp,有两个可变参数:
i变化范围为0-N,rest变化范围,从0-sum/2,不会超过此范围。
先看basecase:
在这里插入图片描述
分析普遍位置依赖关系:
i位置依赖于i+1位置
在这里插入图片描述

   public static int dp1(int[] arr) {if (arr == null || arr.length < 2) {return 0;}int sum = 0;for (int num : arr) {sum += num;}sum /= 2;int N = arr.length;int[][] dp = new int[N + 1][sum + 1];/*int p1 = process(arr, i + 1, rest);// 可能性2,要使用arr[i]int p2 = 0;if (arr[i] <= rest) {p2 = arr[i] + process(arr, i + 1, rest - arr[i]);}*/for (int i = N - 1; i >= 0; i--) {for (int rest = 0; rest <= sum; rest++) {int p1 = dp[i + 1][rest];int p2 = 0;if (arr[i] <= rest) {p2 = arr[i] + dp[i + 1][rest - arr[i]];}dp[i][rest] = Math.max(p1, p2);}}return dp[0][sum];}public static int[] randomArray(int len, int value) {int[] arr = new int[len];for (int i = 0; i < arr.length; i++) {arr[i] = (int) (Math.random() * value);}return arr;}public static void printArray(int[] arr) {for (int num : arr) {System.out.print(num + " ");}System.out.println();}public static void main(String[] args) {int maxLen = 20;int maxValue = 50;int testTime = 10000;System.out.println("测试开始");for (int i = 0; i < testTime; i++) {int len = (int) (Math.random() * maxLen);int[] arr = randomArray(len, maxValue);int ans1 = right(arr);int ans2 = dp1(arr);if (ans1 != ans2) {printArray(arr);System.out.println(ans1);System.out.println(ans2);System.out.println("Oops!");break;}}System.out.println("测试结束");}

题目二

在这里插入图片描述

 public static int right1(int[] arr) {if (arr == null || arr.length < 2) {return 0;}int sum = 0;for (int num : arr) {sum += num;}if ((arr.length & 1) == 0) {return process1(arr, 0, arr.length / 2, sum / 2);} else {return Math.max(process1(arr, 0, arr.length / 2, sum / 2), process1(arr, 0, arr.length / 2 + 1, sum / 2));}}public static int process1(int[] arr, int i, int picks, int rest) {if (i == arr.length) {//没有数的情况,没法调返回一个-1表示这个过程不能使用return picks == 0 ? 0 : -1;} else {//还有数挑//第一种选择不挑当前数int p1 = process1(arr, i + 1, picks, rest);int p2 = -1;int next = -1;if (arr[i] <= rest) {next = process1(arr, i + 1, picks - 1, rest - arr[i]);}if (next != -1) {//如果后续是有效的才有可能性2p2 = arr[i] + next;}return Math.max(p1,p2);}}

改dp:三个可变参数可用一个三维dp解决

在这里插入图片描述

  public static int dp4(int[] arr) {if (arr == null || arr.length < 2) {return 0;}int sum = 0;for (int num : arr) {sum += num;}sum /= 2;int N = arr.length;int M = (N + 1) / 2;int[][][] dp = new int[N + 1][M + 1][sum + 1];for (int i = 0; i <= N; i++) {for (int j = 0; j <= M; j++) {for (int k = 0; k <= sum; k++) {dp[i][j][k] = -1;}}}/*    if (i == arr.length) {//没有数的情况,没法调返回一个-1表示这个过程不能使用return picks == 0 ? 0 : -1;}*/for (int rest = 0; rest <= sum; rest++) {dp[N][0][rest] = 0;}for (int i = N - 1; i >= 0; i--) {for (int picks = 0; picks <= M; picks++) {for (int rest = 0; rest <= sum; rest++) {/*      //还有数挑//第一种选择不挑当前数int p1 = process1(arr, i + 1, picks, rest);int p2 = -1;int next = -1;if (arr[i] <= rest) {next = process1(arr, i + 1, picks - 1, rest - arr[i]);}if (next != -1) {//如果后续是有效的才有可能性2p2 = arr[i] + next;}return Math.max(p1, p2);*/int p1 = dp[i + 1][picks][rest];int p2 = -1;int next = -1;if (picks - 1 >= 0 && arr[i] <= rest) {next = dp[i + 1][picks - 1][rest - arr[i]];}if (next != -1) {p2 = arr[i] + next;}dp[i][picks][rest] = Math.max(p1,p2);}}}if ((arr.length & 1) == 0) {return dp[0][arr.length / 2][sum];} else {return Math.max(dp[0][arr.length / 2][sum], dp[0][(arr.length / 2) + 1][sum]);}}

什么暴力递归可以继续优化

在这里插入图片描述
在这里插入图片描述

暴力递归和动态规划的关系

在这里插入图片描述

面试题和动态规划的关系

在这里插入图片描述

如何找到某个问题的动态规划方式

在这里插入图片描述

面试中设计暴力递归的原则

在这里插入图片描述

知道了暴力递归的原则 然后设计

在这里插入图片描述

常见的四种尝试模型

在这里插入图片描述

如何分析有没有重复解

在这里插入图片描述

暴力递归到动态规划的套路

在这里插入图片描述

动态规划的进一步优化

在这里插入图片描述

N皇后问题

在这里插入图片描述
在这里插入图片描述
如上算是一种解,考虑皇后的时候一行一行的填入皇后,每一行填入一个皇后,这样就不用检查两个皇后是否共行了。
之前的某个皇后在(x,y),然后当前位置在(甲,乙)位置
如果y==乙或者甲减去x的绝对值等于y-乙的绝对值【共斜线】
复杂度为O(n的n次方)
每一行都有n种决策

public static int num1(int n) {if (n < 1) {return 0;}int[] record = new int[n];return process1(0, record, n);}// 当前来到i行,一共是0~N-1行// 在i行上放皇后,所有列都尝试// 必须要保证跟之前所有的皇后不打架// int[] record record[x] = y 之前的第x行的皇后,放在了y列上,一维数组的列号表示n皇后的行号// 返回:不关心i以上发生了什么,i.... 后续有多少合法的方法数public static int process1(int i, int[] record, int n) {//i来到n位置未发生打架if (i == n) {return 1;}int res = 0;// i行的皇后,放哪一列呢?j列,for (int j = 0; j < n; j++) {if (isValid(record, i, j)) {record[i] = j;res += process1(i + 1, record, n);}}return res;}/*** 判断是否发生打架** @param record* @param i* @param j* @return*/public static boolean isValid(int[] record, int i, int j) {// 0..i-1,检查0->i-1行的皇后是否发生打架for (int k = 0; k < i; k++) {if (j == record[k] || Math.abs(record[k] - j) == Math.abs(i - k)) {return false;}}return true;}

位运算优化常数时间:
在这里插入图片描述
能选的位置是列或上左下与右下还是0的位置。
同理再定义一个第0行的x位置是皇后放置的位置,或出来三个方框的位置是第一行不能选的。
在这里插入图片描述
每次放一个皇后都要更新列限制,左下限制以及右下限制。
假设某个时刻是这样的:
在这里插入图片描述
最后是1的不能放皇后是0的可以,然后整体取反变成其他的全1中间的三个1变成三个0
limit是0…011111110…0,然后与一下得到limit=1100011,其中1是能放n皇后的位置

// 请不要超过32皇后问题public static int num2(int n) {if (n < 1 || n > 32) {return 0;}// 如果你是13皇后问题,limit 最右13个1,其他都是0,通过整数的位来标记皇后int limit = n == 32 ? -1 : (1 << n) - 1;return process2(limit, 0, 0, 0);}// 7皇后问题// limit : 0....0 1 1 1 1 1 1 1// 之前皇后的列影响:colLim// 之前皇后的左下对角线影响:leftDiaLim// 之前皇后的右下对角线影响:rightDiaLimpublic static int process2(int limit, int colLim, int leftDiaLim, int rightDiaLim) {//列影响等于了limitif (colLim == limit) {return 1;}// pos中所有是1的位置,是你可以去尝试皇后的位置int pos = limit & (~(colLim | leftDiaLim | rightDiaLim));int mostRightOne = 0;int res = 0;while (pos != 0) {mostRightOne = pos & (~pos + 1);pos = pos - mostRightOne;res += process2(limit, colLim | mostRightOne, (leftDiaLim | mostRightOne) << 1,(rightDiaLim | mostRightOne) >>> 1);//无符号右移}return res;}
http://www.yayakq.cn/news/424014/

相关文章:

  • 门户网站阳光警务执法办案查询wordpress 音乐格式
  • 英文营销网站建设初学者网站建设
  • 林州网站建设服务百度网址大全网址
  • 凡科网站设计做代理的项目在哪个网站
  • 智慧团建网站没有验证码手机网站制作的价格
  • 外部网站 同意加载台山网站开发
  • 模拟炒股网站开发sae storage wordpress
  • 阜阳做网站企业网站维护报价
  • 做再生资源的网站有哪些企业展厅设计公司案例欣赏
  • 网站建设营销开场白做地方门户网站的资质
  • 湖北长安建设网站网站开发项目描述
  • 网站的meta标签优化保定网站设计制作公司
  • 有偿做设计的网站域名如何购买
  • 比较大网站建设公司wordpress源神
  • 海南省住建设厅网站报监的工程山东威海最新消息今天
  • 国家和住房城乡建设部网站首页wordpress登录页面图标修改
  • 网站建设优化多少钱做教育行业网站
  • 建个网站找做水晶接单在哪个网站接
  • 前端做视频直播网站中国档案网站建设现状研究
  • 哪个网站可以接加工单腾讯建设网站视频
  • 汽车配件外贸网站php如何自学做网站
  • 如何做网站吸引广告商wordpress 下一页
  • 重庆玖玺国际做网站做ppt卖给网站
  • 响应式网站开发哪家好如何注册公司公众号
  • 鞍山网站网站建设个人主页怎么找
  • 网站开发外包费用会计科目上海市建设注册管理网站
  • 中国建设银行网站是什么好的龙岗网站建设
  • 实时开奖走势网站建设女生适合学计算机的哪个专业
  • 腾讯网站开发wordpress首页调用页面文章的内容
  • 宣传网站怎么做顺德网站建设价格