精华内容
下载资源
问答
  • Android button 圆角动态更改背景颜色

    千次阅读 2016-10-31 08:40:32
    圆角button实现(左下和右下为圆角) 如果有背景图片切换,可以定义属性  android:id="@+id/ok_btn"  android:layout_width="284dp"  android:layout_height="66dp"  android:layout_align

    最新在升级方面做UI方面的优化,遇到需要在一个圆角型的对话框中最下边的两个方形button分别进行优化成最下角为圆形和右下角圆形,本来是让UED部门进行切图,无奈人言微轻不给切图,只有自己动手实现。

    圆角button实现(左下角和右下角为圆角)

    方法一:如果有背景图片切换,可以定义属性

    <Button
                android:id="@+id/ok_btn"
                android:layout_width="284dp"
                android:layout_height="66dp"
                android:layout_alignParentBottom="true"
                android:layout_marginTop="28dp"
                android:text="@string/detemin_btun"
                android:background="@drawable/upgrade_btn_left_selector"
                android:textColor="@layout/upgrade_bt_textcolor"
                android:textSize="30sp" />

    在drawable中定义upgrade_btn_left_selector.xml文件

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">

        <item android:drawable="@drawable/btn_focus_left" android:state_enabled="true" android:state_focused="true" android:state_pressed="false"/>
        <item android:drawable="@drawable/btn_focus_left" android:state_enabled="true" android:state_pressed="true"/>
        <item android:drawable="@drawable/btn_normal_left"/>

    </selector>

    方法二:没有背景图片切换

    <Button
                android:id="@+id/ok_btn"
                android:layout_width="284dp"
                android:layout_height="66dp"
                android:layout_alignParentBottom="true"
                android:layout_marginTop="28dp"
                android:text="@string/detemin_btun"

                android:background="@drawable/upgrade_btn_left_selector"

                android:textColor="@layout/upgrade_bt_textcolor"
                android:textSize="30sp" />

    在在drawable中定义upgrade_btn_left_selector.xml文件

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
     
        <!--
        <item android:drawable="@drawable/btn_focus_left" android:state_enabled="true" android:state_focused="true" android:state_pressed="false"/>
        <item android:drawable="@drawable/btn_focus_left" android:state_enabled="true" android:state_pressed="true"/>
        <item android:drawable="@drawable/btn_normal_left"/>
        -->
          
        <item android:state_pressed="true"  >
          <shape>  
                <!-- 设置背景填充色 -->  
                <solid android:color="#007AFF"/>
                <!-- 设置边框宽度为1dp,边框颜色 -->  
                <stroke android:width="1dp" android:color="#324061" />  
                <!-- 设置按钮圆角半径为10dp -->  
                <corners android:bottomLeftRadius="10dp" />  
          </shape>
        </item>  
        <item android:state_focused="true"  >
          <shape>  
                <!-- 设置背景填充色 -->  
                <solid android:color="#007AFF"/>
                <!-- 设置边框宽度为1dp,边框颜色 -->  
                <stroke android:width="1dp" android:color="#324061" />   
                <!-- 设置按钮圆角半径为10dp -->  
                <corners android:bottomLeftRadius="10dp" />  
          </shape>
        </item>
        <item android:right="-1dp">
          <shape>  
                <!-- 设置背景填充色 -->  
                <solid android:color="#0A1A42"/>  
                <!-- 设置边框宽度为1dp,边框颜色 -->  
                <stroke android:width="1dp" android:color="#324061" />
                <!-- 设置按钮圆角半径为10dp -->  
                <corners android:bottomLeftRadius="10dp" />  
          </shape>
        </item>
        
    </selector>


    这是综合网上资料结合自身情况具体实现过的,有时间记录下来,下次用到时忘了再随时查看~

    展开全文
  • 由于我们的目的是从左上到右下一共有多少种路径,那我们就定义 dp[i] [j]的含义为: 当机器人从左上走到(i, j) 这个位置时,一共有 dp[i] [j] 种路径 。那么,dp[m-1] [n-1] 就是我们要的答案了。 注意,这个...
        

    对于动态规划,春招秋招时好多题都会用到动态规划,一气之下,再 leetcode 连续刷了几十道动态规划的题

    640?wx_fmt=png
    在这里插入图片描述

    之后,豁然开朗 ,感觉动态规划也不是很难,今天,我就来跟大家讲一讲,我是怎么做动态规划的题的,以及从中学到的一些套路。相信你看完一定有所收获

    如果你对动态规划感兴趣,或者你看的懂动态规划,但却不知道怎么下手,那么我建议你好好看以下,这篇文章的写法,和之前那篇讲递归的写法,是差不多一样的,将会举大量的例子。如果一次性看不完,建议收藏,同时别忘了素质三连

    为了兼顾初学者,我会从最简单的题讲起,后面会越来越难,最后面还会讲解,该如何优化。因为 80% 的动规都是可以进行优化的。不过我得说,如果你连动态规划是什么都没听过,可能这篇文章你也会压力山大。

    一、动态规划的三大步骤

    动态规划,无非就是利用历史记录,来避免我们的重复计算。而这些历史记录,我们得需要一些变量来保存,一般是用一维数组或者二维数组来保存。下面我们先来讲下做动态规划题很重要的三个步骤,

    如果你听不懂,也没关系,下面会有很多例题讲解,估计你就懂了。之所以不配合例题来讲这些步骤,也是为了怕你们脑袋乱了

    第一步骤:定义数组元素的含义,上面说了,我们会用一个数组,来保存历史数组,假设用一维数组 dp[] 吧。这个时候有一个非常非常重要的点,就是规定你这个数组元素的含义,例如你的 dp[i] 是代表什么意思?

    第二步骤:找出数组元素之间的关系式,我觉得动态规划,还是有一点类似于我们高中学习时的归纳法的,当我们要计算 dp[n] 时,是可以利用 dp[n-1],dp[n-2]…..dp[1],来推出 dp[n] 的,也就是可以利用历史数据来推出新的元素值,所以我们要找出数组元素之间的关系式,例如 dp[n] = dp[n-1] + dp[n-2],这个就是他们的关系式了。而这一步,也是最难的一步,后面我会讲几种类型的题来说。

    学过动态规划的可能都经常听到最优子结构,把大的问题拆分成小的问题,说时候,最开始的时候,我是对最优子结构一梦懵逼的。估计你们也听多了,所以这一次,我将换一种形式来讲,不再是各种子问题,各种最优子结构。所以大佬可别喷我再乱讲,因为我说了,这是我自己平时做题的套路。

    第三步骤:找出初始值。学过数学归纳法的都知道,虽然我们知道了数组元素之间的关系式,例如 dp[n] = dp[n-1] + dp[n-2],我们可以通过 dp[n-1] 和 dp[n-2] 来计算 dp[n],但是,我们得知道初始值啊,例如一直推下去的话,会由 dp[3] = dp[2] + dp[1]。而 dp[2] 和 dp[1] 是不能再分解的了,所以我们必须要能够直接获得 dp[2] 和 dp[1] 的值,而这,就是所谓的初始值

    由了初始值,并且有了数组元素之间的关系式,那么我们就可以得到 dp[n] 的值了,而 dp[n] 的含义是由你来定义的,你想求什么,就定义它是什么,这样,这道题也就解出来了。

    不懂?没事,我们来看三四道例题,我讲严格按这个步骤来给大家讲解。

    更多算法原创文章,可以关注我的公众号『苦逼的码农

    二、案例详解

    案例一、简单的一维 DP

    问题描述:一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。

    (1)、定义数组元素的含义

    按我上面的步骤说的,首先我们来定义 dp[i] 的含义,我们的问题是要求青蛙跳上 n 级的台阶总共由多少种跳法,那我们就定义 dp[i] 的含义为:跳上一个 i 级的台阶总共有 dp[i] 种跳法。这样,如果我们能够算出 dp[n],不就是我们要求的答案吗?所以第一步定义完成。

    (2)、找出数组元素间的关系式

    我们的目的是要求 dp[n],动态规划的题,如你们经常听说的那样,就是把一个规模比较大的问题分成几个规模比较小的问题,然后由小的问题推导出大的问题。也就是说,dp[n] 的规模为 n,比它规模小的是 n-1, n-2, n-3…. 也就是说,dp[n] 一定会和 dp[n-1], dp[n-2]….存在某种关系的。我们要找出他们的关系。

    那么问题来了,怎么找?

    这个怎么找,是最核心最难的一个,我们必须回到问题本身来了,来寻找他们的关系式,dp[n] 究竟会等于什么呢?

    对于这道题,由于情况可以选择跳一级,也可以选择跳两级,所以青蛙到达第 n 级的台阶有两种方式

    一种是从第 n-1 级跳上来

    一种是从第 n-2 级跳上来

    由于我们是要算所有可能的跳法的,所以有 dp[n] = dp[n-1] + dp[n-2]。

    (3)、找出初始条件

    当 n = 1 时,dp[1] = dp[0] + dp[-1],而我们是数组是不允许下标为负数的,所以对于 dp[1],我们必须要直接给出它的数值,相当于初始值,显然,dp[1] = 1。一样,dp[0] = 0.(因为 0 个台阶,那肯定是 0 种跳法了)。于是得出初始值:

    dp[0] = 0.

    三个步骤都做出来了,那么我们就来写代码吧,代码会详细注释滴。

    int f( int n ){
        if(n <= 1)
        return n;
        // 先创建一个数组来保存历史数据
        int[] dp = new int[n+1];
        // 给出初始值
        dp[0] = 0;
        dp[1] = 1;
        // 通过关系式来计算出 dp[n]
        for(int i = 2; i <= n; i++){
            dp[i] = dp[i-1] + dp[i-2];
        }
        // 把最终结果返回
        return dp[n];
    }
    
    (4)、再说初始化

    大家先想以下,你觉得,上面的代码有没有问题?

    答是有问题的,还是错的,错在对初始值的寻找不够严谨,这也是我故意这样弄的,意在告诉你们,关于初始值的严谨性。例如对于上面的题,当 n = 2 时,dp[2] = dp[1] + dp[0] = 1。这显然是错误的,你可以模拟一下,应该是 dp[2] = 2。

    也就是说,在寻找初始值的时候,一定要注意不要找漏了,dp[2] 也算是一个初始值,不能通过公式计算得出。有人可能会说,我想不到怎么办?这个很好办,多做几道题就可以了。

    下面我再列举三道不同的例题,并且,再在未来的文章中,我也会持续按照这个步骤,给大家找几道有难度且类型不同的题。下面这几道例题,不会讲的特性详细哈。实际上 ,上面的一维数组是可以把空间优化成更小的,不过我们现在先不讲优化的事,下面的题也是,不讲优化版本。

    案例二:二维数组的 DP

    我做了几十道 DP 的算法题,可以说,80% 的题,都是要用二维数组的,所以下面的题主要以二维数组为主,当然有人可能会说,要用一维还是二维,我怎么知道?这个问题不大,接着往下看。

    问题描述

    一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。

    机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。

    问总共有多少条不同的路径?

    640?wx_fmt=png

    这是 leetcode 的 62 号题:https://leetcode-cn.com/problems/unique-paths/

    还是老样子,三个步骤来解决。

    步骤一、定义数组元素的含义

    由于我们的目的是从左上角到右下角一共有多少种路径,那我们就定义 dp[i] [j]的含义为:当机器人从左上角走到(i, j) 这个位置时,一共有 dp[i] [j] 种路径。那么,dp[m-1] [n-1] 就是我们要的答案了。

    注意,这个网格相当于一个二维数组,数组是从下标为 0 开始算起的,所以 右下角的位置是 (m-1, n - 1),所以 dp[m-1] [n-1] 就是我们要找的答案。

    步骤二:找出关系数组元素间的关系式

    想象以下,机器人要怎么样才能到达 (i, j) 这个位置?由于机器人可以向下走或者向右走,所以有两种方式到达

    一种是从 (i-1, j) 这个位置走一步到达

    一种是从(i, j - 1) 这个位置走一步到达

    因为是计算所有可能的步骤,所以是把所有可能走的路径都加起来,所以关系式是 dp[i] [j] = dp[i-1] [j] + dp[i] [j-1]。

    步骤三、找出初始值

    显然,当 dp[i] [j] 中,如果 i 或者 j 有一个为 0,那么还能使用关系式吗?答是不能的,因为这个时候把 i - 1 或者 j - 1,就变成负数了,数组就会出问题了,所以我们的初始值是计算出所有的 dp[0] [0….n-1] 和所有的 dp[0….m-1] [0]。这个还是非常容易计算的,相当于计算机图中的最上面一行和左边一列。因此初始值如下:

    dp[0] [0….n-1] = 1; // 相当于最上面一行,机器人只能一直往左走

    dp[0…m-1] [0] = 1; // 相当于最左面一列,机器人只能一直往下走

    撸代码

    三个步骤都写出来了,直接看代码

    public static int uniquePaths(int m, int n) {
        if (m <= 0 || n <= 0) {
            return 0;
        }
    
        int[][] dp = new int[m][n]; // 
          // 初始化
          for(int i = 0; i < m; i++){
          dp[i][0] = 1;
        }
          for(int i = 0; i < n; i++){
          dp[0][i] = 1;
        }
            // 推导出 dp[m-1][n-1]
        for (int i = 1; i < m; i++) {
            for (int j = 1; j < n; j++) {
                dp[i][j] = dp[i-1][j] + dp[i][j-1];
            }
        }
        return dp[m-1][n-1];
    }
    

    O(n*m) 的空间复杂度可以优化成 O(min(n, m)) 的空间复杂度的,不过这里先不讲。

    案例三、二维数组 DP

    写到这里,有点累了,,但还是得写下去,所以看的小伙伴,你们可得继续看呀。下面这道题也不难,比上面的难一丢丢,不过也是非常类似

    问题描述

    给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。

    说明:每次只能向下或者向右移动一步。

    举例:
    输入:
    arr = [
      [1,3,1],
      [1,5,1],
      [4,2,1]
    ]
    输出: 7
    解释: 因为路径 1→3→1→1→1 的总和最小。
    

    和上面的差不多,不过是算最优路径和,这是 leetcode 的第64题:https://leetcode-cn.com/problems/minimum-path-sum/

    还是老样子,可能有些人都看烦了,哈哈,但我还是要按照步骤来写,让那些不大懂的加深理解。有人可能觉得,这些题太简单了吧,别慌,小白先入门,这些属于 medium 级别的,后面在给几道 hard 级别的。

    步骤一、定义数组元素的含义

    由于我们的目的是从左上角到右下角,最小路径和是多少,那我们就定义 dp[i] [j]的含义为:当机器人从左上角走到(i, j) 这个位置时,最下的路径和是 dp[i] [j]。那么,dp[m-1] [n-1] 就是我们要的答案了。

    注意,这个网格相当于一个二维数组,数组是从下标为 0 开始算起的,所以 由下角的位置是 (m-1, n - 1),所以 dp[m-1] [n-1] 就是我们要走的答案。

    步骤二:找出关系数组元素间的关系式

    想象以下,机器人要怎么样才能到达 (i, j) 这个位置?由于机器人可以向下走或者向右走,所以有两种方式到达

    一种是从 (i-1, j) 这个位置走一步到达

    一种是从(i, j - 1) 这个位置走一步到达

    不过这次不是计算所有可能路径,而是计算哪一个路径和是最小的,那么我们要从这两种方式中,选择一种,使得dp[i] [j] 的值是最小的,显然有

    dp[i] [j] = min(dp[i-1][j],dp[i][j-1]) + arr[i][j];// arr[i][j] 表示网格种的值
    
    步骤三、找出初始值

    显然,当 dp[i] [j] 中,如果 i 或者 j 有一个为 0,那么还能使用关系式吗?答是不能的,因为这个时候把 i - 1 或者 j - 1,就变成负数了,数组就会出问题了,所以我们的初始值是计算出所有的 dp[0] [0….n-1] 和所有的 dp[0….m-1] [0]。这个还是非常容易计算的,相当于计算机图中的最上面一行和左边一列。因此初始值如下:

    dp[0] [j] = arr[0] [j] + dp[0] [j-1]; // 相当于最上面一行,机器人只能一直往左走

    dp[i] [0] = arr[i] [0] + dp[i] [0];  // 相当于最左面一列,机器人只能一直往下走

    代码如下
    public static int uniquePaths(int[][] arr) {
          int m = arr.length;
          int n = arr[0].length;
        if (m <= 0 || n <= 0) {
            return 0;
        }
    
        int[][] dp = new int[m][n]; // 
          // 初始化
          dp[0][0] = arr[0][0];
          // 初始化最左边的列
          for(int i = 1; i < m; i++){
          dp[i][0] = dp[i-1][0] + arr[i][0];
        }
          // 初始化最上边的行
          for(int i = 1; i < n; i++){
          dp[0][i] = dp[0][i-1] + arr[0][i];
        }
            // 推导出 dp[m-1][n-1]
        for (int i = 1; i < m; i++) {
            for (int j = 1; j < n; j++) {
                dp[i][j] = Math.min(dp[i-1][j], dp[i][j-1]) + arr[i][j];
            }
        }
        return dp[m-1][n-1];
    }
    

    O(n*m) 的空间复杂度可以优化成 O(min(n, m)) 的空间复杂度的,不过这里先不讲。更多原创算法文章,可以关注我的公众号『苦逼的码农』

    案例 4:编辑距离

    这次给的这道题比上面的难一些,在 leetcdoe 的定位是 hard 级别。好像是 leetcode 的第 72 号题。

    问题描述

    给定两个单词 word1 和 word2,计算出将 word1 转换成 word2 所使用的最少操作数 。

    你可以对一个单词进行如下三种操作:

    插入一个字符

    示例 1:
    输入: word1 = "horse", word2 = "ros"
    输出: 3
    解释: 
    horse -> rorse (将 'h' 替换为 'r')
    rorse -> rose (删除 'r')
    rose -> ros (删除 'e')
    

    解答

    还是老样子,按照上面三个步骤来,并且我这里可以告诉你,90% 的字符串问题都可以用动态规划解决,并且90%是采用二维数组。

    步骤一、定义数组元素的含义

    由于我们的目的求将 word1 转换成 word2 所使用的最少操作数 。那我们就定义 dp[i] [j]的含义为:当字符串 word1 的长度为 i,字符串 word2 的长度为 j 时,将 word1 转化为 word2 所使用的最少操作次数为 dp[i] [j]

    有时候,数组的含义并不容易找,所以还是那句话,我给你们一个套路,剩下的还得看你们去领悟。

    步骤二:找出关系数组元素间的关系式

    接下来我们就要找 dp[i] [j] 元素之间的关系了,比起其他题,这道题相对比较难找一点,但是,不管多难找,大部分情况下,dp[i] [j] 和 dp[i-1] [j]、dp[i] [j-1]、dp[i-1] [j-1] 肯定存在某种关系。因为我们的目标就是,从规模小的,通过一些操作,推导出规模大的。对于这道题,我们可以对 word1 进行三种操作

    插入一个字符

    由于我们是要让操作的次数最小,所以我们要寻找最佳操作。那么有如下关系式:

    一、如果我们 word1[i] 与 word2 [j] 相等,这个时候不需要进行任何操作,显然有 dp[i] [j] = dp[i-1] [j-1]。(别忘了 dp[i] [j] 的含义哈)。

    二、如果我们 word1[i] 与 word2 [j] 不相等,这个时候我们就必须进行调整,而调整的操作有 3 种,我们要选择一种。三种操作对应的关系试如下(注意字符串与字符的区别):

    (1)、如果把字符 word1[i] 替换成与 word2[j] 相等,则有 dp[i] [j] = dp[i-1] [j-1] + 1;

    (2)、如果在字符串 word1末尾插入一个与 word2[j] 相等的字符,则有 dp[i] [j] = dp[i] [j-1] + 1;

    (3)、如果把字符 word1[i] 删除,则有 dp[i] [j] = dp[i-1] [j] + 1;

    那么我们应该选择一种操作,使得 dp[i] [j] 的值最小,显然有

    dp[i] [j] = min(dp[i-1] [j-1],dp[i] [j-1],dp[[i-1] [j]]) + 1;

    于是,我们的关系式就推出来了,

    步骤三、找出初始值

    显然,当 dp[i] [j] 中,如果 i 或者 j 有一个为 0,那么还能使用关系式吗?答是不能的,因为这个时候把 i - 1 或者 j - 1,就变成负数了,数组就会出问题了,所以我们的初始值是计算出所有的 dp[0] [0….n] 和所有的 dp[0….m] [0]。这个还是非常容易计算的,因为当有一个字符串的长度为 0 时,转化为另外一个字符串,那就只能一直进行插入或者删除操作了。

    代码如下(可以左右滑动)
    public int minDistance(String word1, String word2) {
        int n1 = word1.length();
        int n2 = word2.length();
        int[][] dp = new int[n1 + 1][n2 + 1];
        // dp[0][0...n2]的初始值
        for (int j = 1; j <= n2; j++) 
            dp[0][j] = dp[0][j - 1] + 1;
        // dp[0...n1][0] 的初始值
        for (int i = 1; i <= n1; i++) dp[i][0] = dp[i - 1][0] + 1;
            // 通过公式推出 dp[n1][n2]
        for (int i = 1; i <= n1; i++) {
            for (int j = 1; j <= n2; j++) {
                  // 如果 word1[i] 与 word2[j] 相等。第 i 个字符对应下标是 i-1
                if (word1.charAt(i - 1) == word2.charAt(j - 1)){
                    p[i][j] = dp[i - 1][j - 1];
                }else {
                   dp[i][j] = Math.min(Math.min(dp[i - 1][j - 1], dp[i][j - 1]), dp[i - 1][j]) + 1;
                }         
            }
        }
        return dp[n1][n2];  
    }
    

    最后说下,如果你要练习,可以去 leetcode,选择动态规划专题,然后连续刷几十道,保证你以后再也不怕动态规划了。当然,遇到很难的,咱还是得挂。

    Leetcode 动态规划直达:https://leetcode-cn.com/tag/dynamic-programming/

    更多算法原创文章,可以关注我的公众号『苦逼的码农

    三、总结

    上面的这些题,基本都是不怎么难的入门题,除了最后一道相对难一点,本来是要在写几道难一点,并且讲如何优化的,不过看了下字数,文章有点长了,关于如何优化的,后面再讲吧,在之后的文章中,我也会按照这个步骤,在给大家讲四五道动态规划 hard 级别的题,会放在每天推文的第二条给大家学习。如果大家感兴趣,文章看的人多,那么优化篇很快就会撸出来,不过感兴趣的人很少的话,动力比较少,可能就会慢一些,所以各位小伙伴,如果觉得有收获,不妨三连走起来,嘻嘻。 

    有道无术,术可成;有术无道,止于术

    欢迎大家关注Java之道公众号

    640?wx_fmt=png

    好文章,我在看❤️

    展开全文
  • 定义经过的所有点的数字之和为该条路径的收益,求到达右下的最大收益。 求解: 用动态规划的方法,从左上开始,计算到达每一个点的最大收益。 /** * 用动态规划方法计算: * 用一个数组result[i][j]...

    今天参加了腾讯在线笔试,题目不是很难,但是自己做的不好,前面的有些知识点是自己不太熟悉,属于不用就忘,仅仅回想起一点肯定是不够用的。
    以前一直以为,到大学之后,所有知识点都可以不再记了,会用就好(用多了确实就记住了),或者用过之后,有个印象,到再需要用的时候再”找回来”就可以了。但是很多知识点是不会经常用的,而真正用到的时候,再去”找回来”成本其实还挺高的,甚至还要付出很大的代价(比如考试的时候)。所以对于不常用的知识点还是需要偶尔复习复习。
    今天编程题,最后一道是动态规划的,当时没弄出来,等到结束之后,马上打开eclipse,几分钟就搞定了。下面总结一下这个题,也算复习一下动态规划。

    题目:
    输入一个矩阵num[m][n],现在从左上角(num[0][0])到达右下角num[m-1][n-1],且只能向下或者向右走。定义经过的所有点的数字之和为该条路径的收益,求到达右下角的最大收益。
    求解:
    用动态规划的方法,从左上角开始,计算到达每一个点的最大收益。

    /**
         * 用动态规划方法计算:
         * 用一个数组result[i][j]保存每一个点i,j的最大收益
         *              num[i][j],                                    i=j=0
         * result[i][j]=result[i][j-1]+num[i][j],                     i=0,j!=0
         *              result[i-1][j]+num[i][j],                     j=0,i!=0
         *              Max(result[i-1][j],result[i][j-1])+num[i][j], i!=0,j!=0
         * 
         * @param num 非空数组num
         * @return 
         */
        public static int[][] getMax(int[][] num){
            int m=num.length;
            if(m==0){//说明数组num为空
                return new int[0][0];
            }
            int n=num[0].length;
            int[][] result=new int[m][n];
            for(int jj=0;jj<n;jj++){
                for(int ii=0;ii<m;ii++){
                    if(ii==0 && jj==0){
                        result[ii][jj]=num[ii][jj];
                        continue;
                    }
                    if(jj==0){
                        result[ii][jj]=result[ii-1][jj]+num[ii][jj];
                        continue;
                    }
                    if(ii==0){
                        result[ii][jj]=result[ii][jj-1]+num[ii][jj];
                        continue;
                    }
                    int maxIJ=Math.max(result[ii][jj-1],result[ii-1][jj]);
                    result[ii][jj]=maxIJ+num[ii][jj];
                }
            }
            return result;
        }

    今天写下来,也算是为自己总是不喜欢做笔记提个醒吧。另外也提醒自己应该多复习复习学过的知识点。像这种面试题,你说不会吧,其实基本都会,但是你写不出来(特别是在考试的时候写不出来)就等于不会。就算学习能力强也没什么用。

    展开全文
  • MFC(5):动态五星绘制小练习

    千次阅读 2018-11-13 18:52:54
    需求说明:绘制一个五星,界面有三个按钮,分别为“大”、“中”、“小”;点击相应的按钮,五星会发生变化 解决思路:在五星的外接圆上,选择五个等分点作为五星的五个顶点;根据相邻点不相连的原则,构建...

    需求说明:绘制一个五角星,界面有三个按钮,分别为“大”、“中”、“小”;点击相应的按钮,五角星会发生变化

    解决思路:在五角星的外接圆上,选择五个等分点作为五角星的五个顶点;根据相邻点不相连的原则,构建五角星的五个顶点;基于外接圆半径大小控制画出五角星的大小

    程序实现:

    (1)创建对话框应用程序DrawPentagram;CTRL + A删除对话框中的默认按钮

    (2)拖拽三个按钮,Caption属性分别设置为“大”、“中”、“小”;ID设置为IDC_BIG、IDC_MIDDLE和IDC_SMALL

    (3)在DrawPentagramDlg.h头文件中,添加绘制五角星的函数声明:

        //绘制空心五角星函数
        void DrawHollowPentagram(double radius);
        //绘制实心五角星
        void DrawSolidPentagram(double radius);

    (4)在DrawPentagramDlg.cpp文件中添加绘制五角星的函数实现

    //空心五角星的实现
    
    void CDrawPentagramDlg::DrawHollowPentagram(double radius)
    {
        //定义五角星的五个点的坐标的数组
        CPoint pts[5];
        //创建画笔工具
        CDC *pDC = GetDC();
        //根据外接圆半径计算每个顶点的坐标
        for(int i = 0; i < 5; i++)
        {
            pts[i].x = (long)(150 - radius * sin((i * 72 + 36) * 2 * 3 * 3.14 / 360));
            pts[i].y = (long)(150 + radius * cos((i * 72 + 36) * 2 * 3 * 3.14 / 360));
        }
        //首先将画笔移动到第一个点,将其与第二个点连接
        for(int i = 0; i < 5; i++)
        {
            pDC->MoveTo(pts[i]);    //线段起点
            pDC->LineTo(pts[(i + 2) % 5]);    //线段终点
        }
    }
    
    
    //实心五角星的实现
    void CDrawPentagramDlg::DrawSolidPentagram(double radius)
    {
    	CDC *pDC = GetDC();
    	CPen penBlue(PS_SOLID, 2, RGB(0, 0, 255));	//创建蓝色画笔
    	CPen *pOldPen = pDC->SelectObject(&penBlue);//将画笔与DC关联
    
    	CBrush brushRed(RGB(0, 0, 255));	//创建蓝色画刷
    	CBrush *pOldBrush = pDC->SelectObject(&brushRed);//将画刷与DC关联
    
    	pDC->SetPolyFillMode(WINDING);	//设置填充色
    	
    	CPoint pts[5];
    
    	for(int i = 0; i < 5; i++)
    	{
    		pts[i].x = (long)(150 - radius * cos((i * 144 - 18) * 3.14 / 180));
    		pts[i].y = (long)(150 + radius * sin((i * 144 - 18) * 3.14 / 180));
    	}
    
    
    	//根据五个定点绘制多边形(五角星的外轮廓)
    	CPoint v[5] = {pts[0], pts[1], pts[2], pts[3], pts[4]};
    
    	pDC->Polygon(v, 5);
    
    	//恢复画笔和画刷工具
    	pDC->SelectObject(pOldPen);
    	pDC->SelectObject(pOldBrush);
    }

    (5)按钮的设计

    //大五角星的绘制
    void CDrawPentagramDlg::OnBnClickedBig()
    {
    	//设置外接圆半径
    	this->Invalidate();
    	this->UpdateWindow();
    	double radius = 100;
    	DrawHollowPentagram(radius);
    	//DrawSolidPentagram(radius);
    }
    
    //中五角星的绘制
    void CDrawPentagramDlg::OnBnClickedMiddle()
    {
    	// TODO: 在此添加控件通知处理程序代码
    	this->Invalidate();
    	this->UpdateWindow();
    	double radius = 75;
    	//DrawHollowPentagram(radius);
    	DrawSolidPentagram(radius);
    }
    
    //小五角星的绘制
    void CDrawPentagramDlg::OnBnClickedSmall()
    {
    	// TODO: 在此添加控件通知处理程序代码
    	this->Invalidate();
    	this->UpdateWindow();
    	double radius = 50;
    	//DrawHollowPentagram(radius);
    	DrawSolidPentagram(radius);
    }

    (6)程序效果图

             

    (7)小结

    熟悉绘图API的使用,了解五角星的构成原理,把握五个定点的连接方式

    展开全文
  • 定义出什么是“状态”,以及在该 “状态”下的“值”后,就要找出不同的状态之间如何迁移――即如何从一个或多个“值”已知的“状态”,求出另一个“状态”的“值” 。状态的迁移可以用递推公式表示,此递推公式也可...
  • 最近项目中遇到这样一个要求...这个是我自定xml定义的一个带圆角边框的背景 现在后台返回的颜色.需要代码中进行修改. GradientDrawable drawable = (GradientDrawable) txtConfirm.getBackground(); drawabl
  • 由于我们的目的是从左上到右下一共有多少种路径,那我们就定义 dp[i] [j]的含义为: 当机器人从左上走到(i, j) 这个位置时,一共有 dp[i] [j] 种路径 。那么,dp[m-1] [n-1] 就是我们要的答案了。 注意,...
  • 首先,我们看一下官方定义: 定义: 动态规划算法是通过拆分问题,定义问题状态和状态之间的关系,使得问题能够以递推(或者说分治)的方式去解决。 动态规划算法的基本思想与分治法类似,也是将待求解的问题分解为若干...
  • 教你彻底学会动态规划——入门篇

    万次阅读 多人点赞 2015-08-11 13:26:41
     递归函数有n个参数,就定义一个n维的数组,数组的下标是递归函数参数的取值范围,数组元素的值是递归函数的返回值,这样就可以从边界值开始, 逐步填充数组,相当于计算递归函数值的逆过程。  规解题的一般...
  • ATX电源引脚定义

    千次阅读 2019-06-14 11:06:26
    无主板启动电源——ATX电源接口各线的定义(注意:电源端,主板端口需镜像) 左下:1#,左上:11#;右上:20# AT电源只要能把电源打开就行了,可现在的ATX电源都是电位控制开关而非机械开关,这...
  • 参考文献:Curvature Scale Space Corner Detector...1.曲率尺度空间(CSS)的点检测子 这一小节主要讲原始的和改进的CSS。 定义曲率: 其中, g(u,σ ) 是高斯函数对σ的偏导数;一个点是一阶偏导数,二个
  • android之tween动画详解

    千次阅读 2015-05-13 20:04:28
    android中一共提供了两种动画,其一便是tween动画,tween动画通过对view的内容进行一系列的图像变换(包括平移,缩放,旋转,改变透明度)来实现动画效果,动画效果的定义可以使用xml,也可以使用编码来实现。...
  • 俯仰 横滚 偏航

    万次阅读 2015-12-14 11:08:45
    一般定义载体的右、前、上三个方向构成右手系,绕向前的轴旋转就是横滚,绕向右的轴旋转就是俯仰,绕向上的轴旋转就是航向
  • ros:tf中的欧拉角定义

    千次阅读 2018-10-22 23:53:33
    欧拉角的定义有许多不同的形式,为了方便使用,本文列出了ros中欧拉定义。为了增加可信度,本文直接采用源码中的注释对ros tf中的欧拉角的定义进行说明。 在Quaternion.h中,存在以下三种设置方法,其中两种与...
  • Android手机屏幕坐标定义

    千次阅读 2017-05-25 18:30:46
    比如activity是怎样切换的,是从左往右还是从上往下,初次写的时候我们经常搞不清android手机屏屏幕坐标是怎么定义的,原点在哪里,X、Y轴又是怎么定义的,如图竖屏时,左上就是原点,坐标为(0, 0),以原点往
  • 缩放起点X坐标(数值、百分数、百分数p,譬如50表示以当前View左上坐标加50px为初始点、50%表示以当前View的左上加上当前View宽高的50%做为初始点、50%p表示以当前View的左上加上父控件宽高的50%做为初始点) ...
  • 本篇文章中,我们一起探讨了OpenCV中Harris点检测相关的知识点,学习了OpenCV中实现Harris点检测的cornerHarris函数的使用方法。此博文一共有两个配套的麻雀虽小但五脏俱全的示例程序,其经过浅墨详细注释过的...
  • 此处为方便理解,根据航空中的使用的RPY角定义再对此进行阐释。欧拉角定义方式上的不确定性带来了很多实际当中的困难,所幸在特定领域内,欧拉角通常有统一的定义方式。当中常用的一种是航空领域的,用“偏航-仰俯-...
  • 一、定义定义角点的几段话: 1、点检测(Corner Detection)是计算机视觉系统中用来获得图像特征的一种方法,广泛应用于运动检测、图像匹配、视频跟踪、三维建模和目标识别等领域中。也称为特征点检测。 ...
  • 前几天遇到一个需求,将动画顺序改为左上到右下展开,例如Material Design中这个样子。 虽然一个个按顺序播放页可以实现,但也太low了,就希望能够找一个简便的方法。(PS. 个人崇尚简约就是美) 仔细...
  • Android动画三部曲之一 View Animation & LayoutAnimation

    万次阅读 多人点赞 2016-01-31 00:25:01
    转载请注明出处:http://blog.csdn.net/crazy1235/article/details/50465885本篇文章对android的Tween动画和帧动画以及布局动画进行总结。Tween动画 XML语法介绍 插值器 Interpolator ...代码定义缩放动画
  • 无人机的偏航,滚动,俯仰解释

    万次阅读 多人点赞 2019-07-01 16:31:05
    1.偏航(yaw) 简单的定义:就是实际航向与计划航向之间的夹角 ,如图所示 深刻的定义:机轴(沿机头方向)水平投影与地轴的夹角,如图所示 或者:如上图所示,机体坐标系xb轴在水平面上投影与地面坐标系xg...
  • 一、定义定义角点的几段话: 1、点检测(Corner Detection)是计算机视觉系统中用来获得图像特征的一种方法,广泛应用于运动检测、图像匹配、视频跟踪、三维建模和目标识别等领域中。也称为特征点检测。 ...
  • 自己是一个不善管理时间的人,有时为了一两个小程序浪费一...规化一下整个系统后决定系统启动后以托盘图标的形式工作,用防QQ右下弹出信息+声音的方式来提醒自己。最近对设计模式和重构细心研究了一下,所以把能完成
  • 动态规划解最长公共子序列(LCS)(附详细填表过程)

    万次阅读 多人点赞 2018-11-20 12:51:34
    子序列形式化定义: 公共子序列定义: 最长公共子序列(以下简称LCS): 方法 蛮力法求解最长公共子序列: 动态规划求解最长公共子序列: 分析规律: 做法: 伪代码: 下面演示下c数组的填表过程:(以求...
  • Mat类定义

    千次阅读 2018-07-02 11:01:44
    / / 创建4 x 4 的对矩阵并在对线上以0.1的比率缩小。 Mat A = Mat::eye(4, 4, CV_32F)*0.1; Mat::create 分配新的阵列数据 (如果需要)。 C++: void Mat::create(int rows, int cols, int type) C++: void ...
  • Harris点及Shi-Tomasi点检测

    万次阅读 多人点赞 2014-03-13 17:32:59
    一、定义定义角点的几段话: 1、点检测(Corner Detection)是计算机视觉系统中用来获得图像特征的一种方法,广泛应用于运动检测、图像匹配、视频跟踪、三维建模和目标识别等领域中。也称为特征点检测...
  • 虚函数 2 之虚函数的定义

    千次阅读 2019-01-24 23:20:34
    1、虚函数的定义 虚函数就是在基类中被关键字 virtual 说明,并在派生类中重新定义的函数。 虚函数的作用是允许在派生类中重新定义与基类同名的函数,并且可以通过基类指针或引用来访问基类和派生类中的同名函数...
  • 流体力学——漩涡运动

    千次阅读 2020-02-28 11:56:26
    定义:涡量和两倍的旋转速度。 涡量是一个矢量,表示空间点的坐标和时间上的函数。 涡线:某一瞬时涡量场的一条曲线,曲线上任意一点的切线方向与该点流体微团的旋转速度方向一致。 涡管:某一瞬时,在涡量场...
  • 如何利用ArcMap定义投影及坐标转换

    万次阅读 2018-08-24 09:48:11
    今天想写的是对数据如何进行定义投影和坐标转换,坐标问题一直是困扰许多人的一个问题,也是每个测绘、测量、gis等工作者再工作学习当中经常碰到的一个问题,对于没有投影信息的图来说,是无法进行投影变换的,所以...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 156,559
精华内容 62,623
关键字:

动角的定义