精华内容
下载资源
问答
  • Android为什么不建议写死dp?

    千次阅读 2019-06-01 10:59:11
    基础:Android中很熟悉的一个概念:dp ...由换算关系得到px = (dp * dpi)/160, 看上去意思是相同dp情况下,dpi越大,px越大,即设备像素密度越高,1个dp代表的实际像素也越多。同理,dpi越小,相同dp时,px也...

    基础:Android中很熟悉的一个概念:dp (density-independent pixels),一个dp代表多少实际像素,与设备dpi相关,与px(像素)换算关系:dp/160 = px/dpi。
    由换算关系得到px = (dp * dpi)/160, 看上去意思是相同dp情况下,dpi越大,px值越大,即设备像素密度越高,1个dp代表的实际像素也越多。同理,dpi越小,相同dp时,px值也越小,这不正好适合做屏幕适配吗?其实大部分情况下是可以的,为什么我又说不建议写死dp呢?
    根本原因我理解是:手机分辨率与设备dpi关系不统一
    什么意思呢?下面举个例子来看。

        <Button
            android:id="@+id/button9"
            android:layout_width="360dp"
            android:layout_height="50dp"
            android:layout_marginTop="8dp"
            android:layout_marginBottom="8dp"
            android:text="Button"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.0"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/imageView"
            app:layout_constraintVertical_bias="0.741" />
    

    简单画了一个Button,宽高都写死,这里只分析宽度值,高度同理。点击按钮会触发以下逻辑:

        private int getDensityDpi() {
            DisplayMetrics dm = new DisplayMetrics();
            Display display = getWindowManager().getDefaultDisplay();
            display.getMetrics(dm);
            Log.i("holaa", "dpi: " + dm.densityDpi);
            Log.i("holaa", "button with(pixels): " + btn.getWidth());
            return dm.densityDpi;
        }
    

    即获取设备密度并打印这个Button实际的px值,btn.getWidth()获取的是px值,这一点注释说的很清楚:

        /**
         * Return the width of your view.
         *
         * @return The width of your view, in pixels.
         */
        @ViewDebug.ExportedProperty(category = "layout")
        public final int getWidth() {
            return mRight - mLeft;
        }
    

    下边看几台分辨率都是1920x1080手机的执行这段代码情况,屏幕尺寸分别是

    1. nexus5: 4.95英寸
    2. nexus5X:5.2
    3. 红米note3: 5.5英寸
      执行结果:
    #nexus5
    I/holaa   ( 2418): dpi: 480
    I/holaa   ( 2418): button with(pixels): 1080
    
    #nexus5X
    05-31 15:47:22.000  1655  1655 I holaa   : dpi: 420
    05-31 15:47:22.000  1655  1655 I holaa   : button with(pixels): 945
    
    #note3
    I/holaa   ( 7577): dpi: 480
    I/holaa   ( 7577): button with(pixels): 1080
    

    截图:
    1.nexus5:
    在这里插入图片描述
    2. nexus5X:
    在这里插入图片描述
    3. 红米note3:
    在这里插入图片描述
    根据现象思考几个问题:

    button宽度(px值)是怎么计算出来的?

    答案是根据dp和px换算关系
    先看nexus5(由于红米note3分辨率和dpi与nexus5一致,不再分析):
    px(btn)= (dp * dpi) /160 = (360 * 480) /160 = 1080px 正好等于屏幕宽度(1080px)
    再看nexus5X:
    px(btn)= (dp * dpi) /160 = (360 * 420) /160 = 945px 发现与nexus5占用的px值不等了,同时界面上出现较大的差异。

    换一种计算思路,nexus5和nexus5X屏幕宽度都是1080px,那么对应换算成dp等于多少?
    nexus5:
    dp(screen)= (px * 160) / dpi = (1080 * 160) / 480 = 360dp
    nexus5X:
    dp(screen)= (px * 160) / dpi = (1080 * 160) / 420 = 411dp
    那么如果我写死Button宽度是360dp就发现问题了,由于两部手机宽度代表的dp值不一致,而Button的宽度是一样的,这导致占用屏幕的比例也就不一样,视觉上当然差别就出来了。

    dpi是谁定义的?

    我理解是手机厂商rom定义的。
    网上很多答案都是根据勾股定理,由分辨率和对角线尺寸计算的每英寸像素数,其实计算出来的是ppi,并不是dpi,二者没有任何关系。ppi是每英寸像素数(pixels per inch),与设备强相关,而dpi是每英寸点数(dots per inch),但是并没说一个点就是一个像素啊。拿以上三部手机来看:
    1.nexus5:ppi = (根号下(1920 * 1920 + 1080 * 1080)) / 4.95 = 445ppi; 通过API获取到的dpi = 480
    2.nexus5X:ppi = (根号下(1920 * 1920 + 1080 * 1080)) / 5.2 = 424ppi; 通过API获取到的dpi = 420
    3.note3:ppi = (根号下(1920 * 1920 + 1080 * 1080)) / 5.5 = 401ppi; 通过API获取到的dpi = 480

    可以看出ppi和dpi没有什么关系,我们平时开发都是用的dpi,这个值不是计算出来的,而是厂商定义的,当然厂商们应该会有一套规范吧,但是实际情况是千差万别,碎片化就是这么来的。如果所有厂商规定分辨率与dpi一一对应,而且分辨率规格固定,比如1920x1070是不合法的,其实没有那么多适配问题,就会像iOS一样适配非常简单,但是现实是屏幕千差万别,dpi千差万别。

    回答问题

    由于手机分辨率与dpi没有直接关系,一般情况下分辨率越高dpi越大,但没有数学关系在里边,屏幕宽高的dp是不一定的,写死dp会产生控件相对屏幕比例失衡,进而导致不同型号手机的布局错乱

    如何应对?

    其实就是如何布局适配问题,目前最好的方式就是用ConstraintLayout,没有之一。大杀器就是ConstraintLayout支持百分比布局,以前官方推出过percentlayout,不过很快就废弃了,而ConstraintLayout是支持百分比布局的。百分比布局完美解决适配问题,一切皆可百分比。有了百分比,控件宽高可成比例,控件占用父布局可成比例,间隙可成比例。另外ConstraintLayout综合了LinearLayout、RelativeLayout、FrameLayout诸多优点,是目前最牛掰的布局方式。

    以下是官方的解释:
    The best way to create a responsive layout for different screen sizes is to use ConstraintLayout as the base layout in your UI. ConstraintLayout allows you to specify the position and size for each view according to spatial relationships with other views in the layout. This way, all the views can move and stretch together as the screen size changes.

    但是ConstraintLayout使用起来相对其他布局较为繁琐,容易写bug。

    展开全文
  • @dimen/activity_vertical_margin 是什么意思? @dimen/activity_vertical_margin这个的意思就是在你的values文件夹下面的dimens文件里面有一个name叫做activity_vertical_margin的项,这个项里面就是你android:...
    @dimen/activity_vertical_margin  是什么意思?
    @dimen/activity_vertical_margin这个的意思就是在你的values文件夹下面的dimens文件里面有一个name叫做activity_vertical_margin的项,
    这个项里面值就是你android:paddingBottom的值,比如:
    <dimen name="activity_vertical_margin">10dp</dimen>
    android:paddingBottom=“@dimen/activity_vertical_margin”
    等价于:
    android:paddingBottom="10dp"
    如果想设定边距可以写为:
    android:paddingBottom="20dp" 。
    不过这种写法不太建议,正规开发的规范写法是把尺寸放入dimens文件中,也就是android:paddingBottom=“@dimen/activity_vertical_margin”
    
    
    
    
    来源:
    http://www.cnblogs.com/yanpanjiao/p/4596266.html
    展开全文
  • dp专题

    2021-04-24 13:02:47
    用到二维dp的时候,通常一维是枚举,二维是限制 ...那么这个余数到底是什么意思呢,我要从哪个集合递推过来呢, 设余数为sum%k 则这个加了v之后再mod k应该也要是j 也就是说 sum+v[i] %k ==j 等价于sum%k + v[i]%k

    用到二维dp的时候,通常一维是枚举,二维是限制
    1.初始化dp【】【】
    2.两层for循环求出状态转移方程

    在这里插入图片描述
    dp[i][j]表示枚举到第i个物品的时候余数为j的dp值
    枚举到第i个物品时
    1.不选第i个物品dp[i][j]=dp[i-1][j]
    2.选第i个物品 dp[i][j]=dp[i-1][ 余数 ]
    那么这个余数到底是什么意思呢,我要从哪个集合递推过来呢,
    设余数为sum%k
    则这个值加了v之后再mod k应该也要是j
    也就是说 sum+v[i] %k ==j

    等价于sum%k + v[i]%k %k==j
    我现在要求sum%k
    解得sum%k=(j-v)%k
    为了防止有负数,所以加个k
    最终的状态转移方程就是
    dp[i][j]=max(dp[i-1][j] , dp[i-1][ (j-v[i] +k)%k] +v[i] )
    通过集合的思想来想出这个状态转移方程

    #include <iostream>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    int dp[110][100],n,m,k,v;
    int main(){
        cin>>n>>k;
        memset(dp,128,sizeof dp);
        dp[0][0]=0;
        for(int i=1;i<=n;i++){
            cin>>v;
            for(int j=0;j<k;j++){
                dp[i][j]=max(dp[i-1][j],dp[i-1][    (   j-v%k  +k)%k  ]+v);
            }
        }
        cout<<dp[n][0];
    }
    

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

    #include <iostream>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    int t,n,m,nn;
    int dp[100][100];
    
    int dfs(int x,int y){
        if(x==0)return dp[x][y]=1;
        if(y==0)return dp[x][y]=0;
        if(y>x)return dp[x][x]=dfs(x,x);
        return dp[x][y]=dfs(x-y,y)+dfs(x,y-1);
    }
    
    int main(){
        cin>>t;
        while(t--){
            cin>>m>>n;
            cout<<dfs(m,n)<<endl;
        }
    }
    

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

    #include <iostream>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    int dp[1001][1001],n;
    string s;
    //char s[1001];
    
    int dfs(int i,int j){
        if(i<0||j<0)return 0;
        if(i==j)return dp[i][j]=0;
        if(s[i]==s[j]&&j-i==1)return dp[i][j]=0;
        if(s[i]==s[j]&&j-i>1)return dp[i][j]=dfs(i+1,j-1);
        return dp[i][j]=min(dfs(i+1,j)+1, dfs(i,j-1)+1);
    }
    
    int main(){
        memset(dp,127,sizeof dp);
        cin>>s;
        n=s.length();
        cout<<dfs(0,n-1)<<endl;
    }
    

    #include <iostream>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    int dp[1001][1001],n;
    string s;
    int main(){
        memset(dp ,127,sizeof dp);
        cin>>s;
        n=s.length();
        n--;
        for(int i=n;i>=0;i--){
            for(int j=i;j<=n;j++){
                if(i==j)dp[i][j]=0;
                else {
                    if(s[i]==s[j]&&(j-i)==1)dp[i][j]=0;
                    else if(s[i]==s[j]&&(j-i)>1)dp[i][j]=dp[i+1][j-1];
                    else dp[i][j]=min(dp[i+1][j]+1,dp[i][j-1]+1)  ;
                }
            }
        }
        cout<<dp[0][n];
    }
    

    在这里插入图片描述

    using namespace std;
    typedef long long LL;
    const int N = 1e5+10;
    LL f[N],ans=INT_MIN;
    int n,w[N],fa[N],root;
    int h[N],e[2*N],ne[2*N],idx;
    void add(int a,int b)
    {
        e[idx]=b,ne[idx]=h[a],h[a]=idx++;
    }
    int dfs(int u,int pre)
    {
        f[u]=(LL)w[u];  //f[u]初始值包括它自己
        for(int i=h[u];i!=-1;i=ne[i])
        {
            int j=e[i];
            if(j!=pre)
            {
                dfs(j,u);
                f[u]+=max((LL)0,f[j]);  //f[u]加上子节点搜索到的最大值
                ans=max(ans,f[u]);  //更新最大值
            }
        }
    }
    int main()
    {
        memset(h,-1,sizeof h);
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&w[i]);
            fa[i]=i;
        }
        int a,b;
        for(int i=0;i<n-1;i++)
        {
            scanf("%d%d",&a,&b);
            add(a,b),add(b,a);
            fa[a]=b;
        }
        for(int i=1;i<=n;i++)
        {
            if(fa[i]==i)    //找到一个根节点
            {
                root=i;
                break;
            }
        }
        dfs(root,-1);   //对根节点进行搜索
        cout<<ans;
        return 0;
    }
    
    作者:GRID
    链接:https://www.acwing.com/solution/content/37555/
    来源:AcWing
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    

    树形DP
    状态划分
    集合:f[u]再以u为根的子树中包含u的所有连通块的权值的最大值
    直接爆搜f[u] = W[u] + 所有连边的其他连通块的最大值,即统计一下就ok
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cstdio>
    #define N 100010
    #define M N*2
    using namespace std;
    
    typedef long long LL;
    
    int n;
    int w[N];
    int h[N],e[M],ne[M],idx;
    LL f[N];
    
    void add(int a,int b)
    {
        e[idx] = b;
        ne[idx] = h[a];
        h[a] = idx ++;
    }
    
    void dfs(int u,int father)
    {
        f[u] = w[u];
        for(int i = h[u];i != -1;i = ne[i])
        {
            int j = e[i];
            if(j != father)
            {
                dfs(j,u);
                f[u] += max(0ll,f[j]);
            }
        }
    }
    
    int main()
    {
        scanf("%d",&n);
        memset(h,-1,sizeof h);
    
        for(int i = 1;i <= n;i ++)  scanf("%d",&w[i]);
        for(int i = 0;i < n - 1;i ++)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            add(a,b),add(b,a);
        }
    
        dfs(1,-1);
    
        LL res = f[1];
        for(int i = 2;i <= n;i ++)  res = max(res,f[i]);
    
        printf("%lld\n",res);
    
        return 0;
    }
    
    作者:Bear_King
    链接:https://www.acwing.com/solution/content/35728/
    来源:AcWing
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    
    展开全文
  • 在數學領域中, programming 指「最佳化( optimization )」的意思,例如求極大、求極小。 dynamic 指「動態」的意思。顧名思義, Dynamic Programming 一個以動態的方式來進行最佳化的方法。 老朱说 ...
    Dynamic Programming

    中文譯作「動態規劃」,英文常常縮寫成 DP 。在數學領域中, programming 是指「最佳化( optimization )」的意思,例如求極大值、求極小值。 dynamic 是指「動態」的意思。顧名思義, Dynamic Programming 是一個以動態的方式來進行最佳化的方法。

    老朱说 《《代码之美》》里面翻译做 动态编程, 不知道真假?

    看来翻译点东西也不容易。
    展开全文
  • 这个问题是在我挑选模拟视频放大器芯片的时候遇到的,当时很不明白放大器的这个参数到底是什么意思,现在知道了,记录在这里,也供大家参考。 差分增益是亮度变化时色饱和度变化的百分比。差分相位是亮度变化时的...
  • 概率dp 神仙题

    2020-09-26 13:11:33
    题目大致意思: 总共有n种邮票,每选一张邮票,邮票的价格会加一,邮票的初始值是1,最后问拿完n种邮票的期望价格。 思路: 发表一下看这个题题解的感想:这个题太仙了,概率dp的套路司空见惯就是把数组定义成已经...
  • 思路:可以比较简单的推出dp方程是什么 dp[i][j] 表示的是当前有i块儿,在第j个数的时候的不相交区间和的最大那么 dp[i][j] = max(dp[i][j-1] + a[j] , dp[i-1][k]+a[j] )其中 0大概意思就是dp[i][j] 可以由 ...
  • 很简单的回答就是,DP中的P就是programing 的意思一种记录,对于递归的低效性,很大一部分来源于对于单个问题的重复计算,我们使用一个数组(一维,或者二维)来记录我们已经求解得到的,就可以大大提高算法的...
  • 【ZOJ4257】MostPowerful 这个题从早饭看到晚饭,真的,看到快吐了, 题意:这个题的大致意思就是,现在有很多的原子,然后这些原子之间...为什么很多的题都用0表示有的意思而不是用1 呢,这因为这样用的话...
  • 之前有人说周源讲的错的 其实应该什么问题的 可以O(n)求出 不过这题hdu上的数据不知道怎么了 = = 反正我在网上找的ac代码们全都TLE。。。。 总之……意思明白就好 反正也入门题…… #include #include
  • 题目还是能看懂的,不想道路游戏那题,我完全不知道题目是什么意思…… GREED_VI大佬第一次用的是二分的思想,于是我就学习了 洛谷测评机快,因此可以过,不过想在CCF老年机上过,就需要优化了 先打了二分的 ...
  • 思路:观察样例,srf先手和qtc先手的答案就是取了个负号。所以就考虑srf先手的时候获得的得分-qtc得分的最大。...qtc先手,题目的意思实际上想让你先考虑qtc-srf获得的最大得分,同样的,此时把qtc看成srf即.
  • 什么意思? 波峰波谷的差值一定中间之差的和,那么波峰波谷就是看成了能不能做差做下去。 比如1254367,从前往后差分 -1,-3,1,2,-3,-1,7.会发现这样一个事情。把正数的差分全部加上去,就是最后...
  • 什么这两题要放到一起说呢,主要这两题十分类似,用单调队列优化的方法一样的,所以放在一起总结会比较印象深刻。 先说POJ3017----------Cut the Sequence 题目地址:http://poj.org/problem?id=3017 题目...
  • 第一步骤:定义数组元素的含义,dp[i] 代表什么意思? 第二步骤:找出数组元素之间的关系式,例如 dp[n] = dp[n-1] + 1。 第三步骤:初始。 1.上楼问题 题目:一次允许上一步或者两步,到第n个台阶有几种方法? ...
  • 动态规划

    2020-08-31 18:20:36
    第⼀步骤:定义数组元素的含义,就是规定你这个数组元素的含义,例如你的 dp[i] 代表什么意思? 第⼆步骤:找出数组元素之间的关系式,有⼀点类似于我们⾼中学习时的归纳法的,当我们要计算 dp[n] 时,可以利⽤ ...
  • 是dp,真的我不会什么最近就整什么,哈哈哈,不过也没关系,可以学习一下,不过过段时间要系统的学一下 推理过程: 这个意思就是说把所有的东西分成2堆,求他们的差值最小 转换一下也就是求一半时的的最大...
  • ST表一种预处理状态,然后利用RMQ O(1)查询答案的技巧,这在黄学长博客上找到的最简单的ST表来写了一法,大致明白什么意思。 ST表难点在于状态转换方程,如果将转换方程换一换又可以求其他东西。 本题中的dp...
  • 今天这篇文章,就结合我个人的理解,和大家聊聊adjustViewBounds到底是什么意思。 首先,澄清两个概念:ImageView和图片 ImageView:Android里用来显示图片的控件。ImageView的长宽可以设定为固定:比如,100dp...
  • 如果我们把这个树按dfs序转化成数列之后可以发现,问题变成了:现在有一段连续的dfs序的节点不能够被选则,问除去这一段的其他节点最大贡献是什么? 可以发现,若是转化成数列,就是很简单的背包,但是要如何解决把...
  • hdu Chopsticks

    2013-07-29 10:18:40
    题目分析: 些题大概意思是说,有N条不同长度的筷子,在题目中按照非递减的顺序输入。 要求找出K+8 对(每对三根筷子使得每一对的最后两根的差的平方总和最少。)并输出最少。...这里为什么是dp
  • 题目的意思是给你两个数字(多达10^6位) ...看完题目就会知道,这个题目一定不是dp,或者说根本不是什么高端的算法,那是什么呢? 对,你没有猜错——贪心。 为什么可以用贪心呢?我们比较一个数,都是从...
  • 搬寝室(hdu-1421)

    千次阅读 2015-05-18 16:23:48
    后来参考别人的做法dp[i][j]表示在i件物品中选j对所需的最小疲劳,相信几乎所有题解都是这么写的,你们也看烦了,那我就说说是什么意思吧 :由于这些东西的重量可以打乱,那我们不妨排序,则肯定拿相邻的两件最好...
  • 动规数组表示的意思dp[i]表示i这个数的所有组合中乘积最大是多少,子问题是什么,使用当前一个数字作为组合后,剩下的的所有组合中乘积最大是多少 注意有几个特殊情况!! 当target <= 4的时候,(不包括1,...
  • 具体RMQ的意思为区间最值查询,他先预处理出来每一段的最值,然后查询的时候直接O(1)的复杂度得出结果。其实还是个dp。用Rmin[i][j]表示从i开始长度为2^j这个区间的最值。至于为什么是2^j,因为计算机当中二进制...
  • s7-300工程实战总结.pdf

    2009-07-24 18:50:49
    64. 功能块DP_SEND、DP_RECV"的返回值代表什么意思,如何理解? 16 65. DP从站,CP模板以及CPU之间的数据通讯过程如何进行的? 16 66. 通过CP342-5,如何实现对PROFIBUS网络和站点的诊断功能? 16 67. 为什么当CP...
  • 初见就没弄懂题目什么意思,看题解也不是很明白,后来自己弄懂了。 首先,n 枚骰子掷出的点数的范围 [n, 6*n],根据排列组合,所有投掷的总可能性 这道题可以使用DP 分解状态时,我们理解为每一次投掷一个...

空空如也

空空如也

1 2
收藏数 36
精华内容 14
关键字:

dp值是什么意思