导航:首页 > 程序命令 > 程序员dp

程序员dp

发布时间:2022-12-08 05:08:19

1. 程序员算法基础——贪心算法

贪心是人类自带的能力,贪心算法是在贪心决策上进行统筹规划的统称。

比如一道常见的算法笔试题---- 跳一跳

我们自然而然能产生一种解法:尽可能的往右跳,看最后是否能到达。
本文即是对这种贪心决策的介绍。

狭义的贪心算法指的是解最优化问题的一种特殊方法,解决过程中总是做出当下最好的选择,因为具有最优子结构的特点,局部最优解可以得到全局最优解;这种贪心算法是动态规划的一种特例。 能用贪心解决的问题,也可以用动态规划解决。

而广义的贪心指的是一种通用的贪心策略,基于当前局面而进行贪心决策。以 跳一跳 的题目为例:
我们发现的题目的核心在于 向右能到达的最远距离 ,我们用maxRight来表示;
此时有一种贪心的策略:从第1个盒子开始向右遍历,对于每个经过的盒子,不断更新maxRight的值。

贪心的思考过程类似动态规划,依旧是两步: 大事化小 小事化了
大事化小:
一个较大的问题,通过找到与子问题的重叠,把复杂的问题划分为多个小问题;
小事化了:
从小问题找到决策的核心,确定一种得到最优解的策略,比如跳一跳中的 向右能到达的最远距离

在证明局部的最优解是否可以推出全局最优解的时候,常会用到数学的证明方式。

如果是动态规划:
要凑出m元,必须先凑出m-1、m-2、m-5、m-10元,我们用dp[i]表示凑出i元的最少纸币数;
有 dp[i]=min(dp[i-1], dp[i-2], dp[i-5], dp[i-10]) + 1 ;
容易知道 dp[1]=dp[2]=dp[5]=dp[10]=1 ;
根据以上递推方程和初始化信息,可以容易推出dp[1~m]的所有值。

似乎有些不对? 平时我们找零钱有这么复杂吗?
从贪心算法角度出发,当m>10且我们有10元纸币,我们优先使用10元纸币,然后再是5元、2元、1元纸币。
从日常生活的经验知道,这么做是正确的,但是为什么?

假如我们把题目变成这样,原来的策略还能生效吗?

接下来我们来分析这种策略:
已知对于m元纸币,1,2,5元纸币使用了a,b,c张,我们有a+2b+5c=m;
假设存在一种情况,1、2、5元纸币使用数是x,y,z张,使用了更少的5元纸币(z<c),且纸币张数更少(x+y+z<a+b+c),即是用更少5元纸币得到最优解。
我们令k=5*(c-z),k元纸币需要floor(k/2)张2元纸币,k%2张1元纸币;(因为如果有2张1元纸币,可以使用1张2元纸币来替代,故而1元纸币只能是0张或者1张)
容易知道,减少(c-z)张5元纸币,需要增加floor(5*(c-z)/2)张2元纸币和(5*(c-z))%2张纸币,而这使得x+y+z必然大于a+b+c。
由此我们知道不可能存在使用更少5元纸币的更优解。
所以优先使用大额纸币是一种正确的贪心选择。

对于1、5、7元纸币,比如说要凑出10元,如果优先使用7元纸币,则张数是4;(1+1+1+7)
但如果只使用5元纸币,则张数是2;(5+5)
在这种情况下,优先使用大额纸币是不正确的贪心选择。(但用动态规划仍能得到最优解)

如果是动态规划:
前i秒的完成的任务数,可以由前面1~i-1秒的任务完成数推过来。
我们用 dp[i]表示前i秒能完成的任务数
在计算前i秒能完成的任务数时,对于第j个任务,我们有两种决策:
1、不执行这个任务,那么dp[i]没有变化;
2、执行这个任务,那么必须腾出来(Sj, Tj)这段时间,那么 dp[i] = max(dp[i], dp[ S[j] ] ) + 1 ;
比如说对于任务j如果是第5秒开始第10秒结束,如果i>=10,那么有 dp[i]=max(dp[i], dp[5] + 1); (相当于把第5秒到第i秒的时间分配给任务j)

再考虑贪心的策略,现实生活中人们是如何安排这种多任务的事情?我换一种描述方式:

我们自然而然会想到一个策略: 先把结束时间早的兼职给做了!
为什么?
因为先做完这个结束时间早的,能留出更多的时间做其他兼职。
我们天生具备了这种优化决策的能力。

这是一道 LeetCode题目 。
这个题目不能直接用动态规划去解,比如用dp[i]表示前i个人需要的最少糖果数。
因为(前i个人的最少糖果数)这种状态表示会收到第i+1个人的影响,如果a[i]>a[i+1],那么第i个人应该比第i+1个人多。
即是 这种状态表示不具备无后效性。

如果是我们分配糖果,我们应该怎么分配?
答案是: 从分数最低的开始。
按照分数排序,从最低开始分,每次判断是否比左右的分数高。
假设每个人分c[i]个糖果,那么对于第i个人有 c[i]=max(c[i-1],c[c+1])+1 ; (c[i]默认为0,如果在计算i的时候,c[i-1]为0,表示i-1的分数比i高)
但是,这样解决的时间复杂度为 O(NLogN) ,主要瓶颈是在排序。
如果提交,会得到 Time Limit Exceeded 的提示。

我们需要对贪心的策略进行优化:
我们把左右两种情况分开看。
如果只考虑比左边的人分数高时,容易得到策略:
从左到右遍历,如果a[i]>a[i-1],则有c[i]=c[i-1]+1;否则c[i]=1。

再考虑比右边的人分数高时,此时我们要从数组的最右边,向左开始遍历:
如果a[i]>a[i+1], 则有c[i]=c[i+1]+1;否则c[i]不变;

这样讲过两次遍历,我们可以得到一个分配方案,并且时间复杂度是 O(N)

题目给出关键信息:1、两个人过河,耗时为较长的时间;
还有隐藏的信息:2、两个人过河后,需要有一个人把船开回去;
要保证总时间尽可能小,这里有两个关键原则: 应该使得两个人时间差尽可能小(减少浪费),同时船回去的时间也尽可能小(减少等待)。

先不考虑空船回来的情况,如果有无限多的船,那么应该怎么分配?
答案: 每次从剩下的人选择耗时最长的人,再选择与他耗时最接近的人。

再考虑只有一条船的情况,假设有A/B/C三个人,并且耗时A<B<C。
那么最快的方案是:A+B去, A回;A+C去;总耗时是A+B+C。(因为A是最快的,让其他人来回时间只会更长, 减少等待的原则

如果有A/B/C/D四个人,且耗时A<B<C<D,这时有两种方案:
1、最快的来回送人方式,A+B去;A回;A+C去,A回;A+D去; 总耗时是B+C+D+2A (减少等待原则)
2、最快和次快一起送人方式,A+B先去,A回;C+D去,B回;A+B去;总耗时是 3B+D+A (减少浪费原则)
对比方案1、2的选择,我们发现差别仅在A+C和2B;
为何方案1、2差别里没有D?
因为D最终一定要过河,且耗时一定为D。

如果有A/B/C/D/E 5个人,且耗时A<B<C<D<E,这时如何抉择?
仍是从最慢的E看。(参考我们无限多船的情况)
方案1,减少等待;先送E过去,然后接着考虑四个人的情况;
方案2,减少浪费;先送E/D过去,然后接着考虑A/B/C三个人的情况;(4人的时候的方案2)

到5个人的时候,我们已经明显发了一个特点:问题是重复,且可以由子问题去解决。
根据5个人的情况,我们可以推出状态转移方程 dp[i] = min(dp[i - 1] + a[i] + a[1], dp[i - 2] + a[2] + a[1] + a[i] + a[2]);
再根据我们考虑的1、2、3、4个人的情况,我们分别可以算出dp[i]的初始化值:
dp[1] = a[1];
dp[2] = a[2];
dp[3] = a[2]+a[1]+a[3];
dp[4] = min(dp[3] + a[4] + a[1], dp[2]+a[2]+a[1]+a[4]+a[2]);

由上述的状态转移方程和初始化值,我们可以推出dp[n]的值。

贪心的学习过程,就是对自己的思考进行优化。
是把握已有信息,进行最优化决策。
这里还有一些收集的 贪心练习题 ,可以实践练习。
这里 还有在线分享,欢迎报名。

2. 安卓设计规范

在讲安卓设计规范之前我们先来看看一下的问题:

*规范是什么?

*规范的目的是什么?

*怎样进行规范?

规范是什么

规范:意指明文规定或约定成俗的标准。或是按照标准,规范的要求进行操作,使某一行为或某一活动达到或是超越规定的标准。

也就是说 规范通过制定一些规定与约束 (如字体大小,界面尺寸,图标大小等) 使某一行为 (如项目开发,组件库的组件等) 达到标准 。

制定规范的目的是 确保设计的统一性与合理性 。规范维护的是项目的统一,而不是设计师个人的设计。想一想在公司里,除了设计,前有产品经理,后有程序员,还有用户,你做的东西都是要交给他们的。产品经理看你的设计是否展现了她的需求(设计内容是否包括前期讨论的内容),程序员问你要各种切图(图标、组件、布局、间距、字体大小等),用户看你的设计(颜色,图标使用的大小范围等),如果设计师完全没有规范,全凭自己的“天马行空”设计出来的东西,是会带来很大的麻烦的,举个简单的例子,切图规范,如果你的命名只有自己能看懂,那你就不要发给程序员了吧~因为发给他他也找不到哪个是哪个,这个图标应该放在哪里。你所做的设计是为了公司项目服务的,是为了客户服务的,所以你设计的东西就得满足项目中其他职位(产品经理、程序员)使用的需求,以及符合用户的使用习惯。所以 规范是为了项目利益最大化,高效化而在团队中制定成的约定。

不同的规范虽然内容不同但是包含的内容其实是差不多的,通常包括布局,颜色,图标,组件,字体这几个方面。接下来我们就来看看安卓中常见的设计规范,相信学习了之后,以后项目里的设计规范你都很清楚了,在设计中多加注意就行。一个产品设计完成之后,进行设计规范制作也是对项目总结的一个方法。能注意规范且会制定规范。

在进行app设计的时候,我们都会先建画布大小,当然是根据安卓界面尺寸来建立的。安卓手机那么多,不必每一个都记住。只要记住一两个,懂得之间的换算关系就行了。

目前安卓端主流尺寸主要是@1.5x,@2x以及@3x,记住下面三个就够用了。

@1.5x    480x854 /540x960

@2x      720x1280( 这是我最常用的界面尺寸)

@3x      1080x1920

考考你,那@1x是多少呢?

除了知道界面尺寸外,还得知道状态栏,导航栏,菜单栏的高度是多少,设计时建立好相应的参考线。

建议取用 720 ×1280 这个尺寸,这个尺寸 720×1280中显示完美,切图后的图片文件大小也适中,应用的内存消耗也不会过高。

对于图标其实在规范上面有很多要注意的,比如图标大小,图标设计,图标切图规范,这里就重点讲图标大小,之后会再讲图标设计规范。

安卓系统中,中文使用的是谷歌思源,英文使用的是Roboto。思源字体,是一种非衬线字体,Adobe称思源体为Source Han Sans,Google称思源体为Noto Sans CJK. 思源体包含7个自重,也就是7中不同粗细的字体。

对于字体或许在设计过程中你会选用其他字体,但是需要注意你所用的字体是否利于用户阅读,是否舒服等问题。

对于字体的大小,在界面设计过程中,需要统一,比如所有正文是统一大小,所有标题是统一大小。

不同风格的字体大小,给人的感觉也是不同的,我们要学会灵活应用。安卓文字单位是sp,以下文字是按照@1x倍率来规范的

在安卓中,标注距离一般用dp,标注文字用sp,而知之间的换算关系为:

1dp=(屏幕ppi/160)px

不清楚单位的,可以去找上一篇文章了解px pt sp dp ppi。

android开发需要的设计交付物至少要有:高保真UI图,标注,切图

这是最后,也是最重要的一点,因为你所切的图是要交到程序员的手里的,他写的程序达不到你想要的效果可能就是他看不懂你给他的规范~

1.切图尺寸必须为双数

2.单像素的图会出现边缘模糊的情况

3.命名需要规范

基本上 App 的切图可分为下面几大类: 背景、按钮、图示、图片、照片、TabBar icon 等。

一般命名规范可以为:

前缀:位置 组件 用途

后缀:状态

如用btn-xxx.png 来命名 。App 里的按钮拥有 4 种属性,分别为一般normal、点击highlight、不能点击disabled、选中(selected)。

但不追求精致与完整度的话,只出一般属性按钮图档就可以了。如果是点击(hightlight)状态就可以命名为:btn- cancel-hightlight.png  表示取消按钮点击时图标。

就算不是按照很严格的规范来命名,至少能让程序员知道你这个图标是在那种情况下使用的图标,这就需要设计师跟程序员很好的沟通,方便整个团队的开发,提高团队的开发效率

3. Android 关于"尺寸"的那些事(dp,dip,sp,pt,px...)

屏幕大小:屏幕大小是手机对角线的物理尺寸,以英寸inch为单位。比如我的Mix 2手机屏幕大小为5.99 inches,意味着我的屏幕对角线长度为5.99inches = 5.99 * 2.54 = 15.2146cm

分辨率:屏幕的像素点数,一般表示为a*b。例如某手机分辨率为21601080,意味着手机屏幕的竖直方向(长)有2160个像素点,水平方向(宽)有1080个像素点。

px :Pixels ,像素;对应屏幕上的实际像素,是画面中最小的点(单位色块),像素大小没有固定长度值,不同设备上1个单位像素色块大小不同。

这么说可能有点陌生,用屏幕分辨率来说,今年流行起来的“全面屏”分辨率是 2160*1080,但是你也可以发现,虽然很多全面屏手机分辨率一样,但是明显看得出来屏幕大小不一样,这也解释了“不同设备像素色块大小是不同的”。

pt :1pt=1/72 inch,用于印刷业,非常简单易用;

dpi :Dots Per Inch,每英寸点数;详见ppi

ppi :Pixels Per Inch,每英寸像素数;数值越大显示越细腻。计算式:ppi = 屏幕对角线像素数 / 屏幕对角线长度。

还是举全面屏的例子,分辨率2160*1080,屏幕大小是5.9inches,勾股定理可以得到对角线像素数大约是2415,那么ppi = 2415 / 5.99 = 403.

事实上dpi 和 ppi 一定程度上可以划等号,都表示像素密度,计算方式完全一致,只不过使用场景不一样。dpi中的dots点属于打印或印刷等领域,例如drawable 文件对应的就是dpi,而ppi中的pixel属于屏幕显示等领域

dp/dip : Density-independent Pixels,密度无关像素 - 基于屏幕物理密度的抽象单位。1dp等于 160 dpi 屏幕上的dpx,这是 系统为“中”密度屏幕假设的基线密度。在运行时,系统 根据使用中屏幕的实际密度按需要以透明方式处理 dp 单位的任何缩放 。dp 单位转换为屏幕像素很简单:px = dp * (dpi / 160)。 例如,在 240 dpi 屏幕上,1 dp 等于 1.5 物理像素。在定义应用的 UI 时应始终使用 dp 单位 ,以确保在不同密度的屏幕上正常显示 UI。

如果看完文章还是觉得很懵,那么可以直接记住: 1dp单位在设备屏幕上总是等于1/160 inch。

sp :Scale-independent Pixels ,与 dp 单位相似,也会根据用户的字体大小偏好进行缩放。

首先我们放上源码中对尺寸单位的转换

可以看到,输入值类型为dp时,返回 value * DisplayMetrics.density,到这里我们可能会发懵:嗯?不对啊,前面我们不是通过px 和 dp 的换算公式来计算的么,怎么这里就简简单单乘了一个DisplayMetrics.density?不要慌,我们先看看源码中对DisplayMetrics.density的介绍。

源码注释中说到“在160dpi的屏幕下,density的值为1,而在120dpi的屏幕下,density的值为0.75”,我们可以大胆的猜测一下,120dpi下的density=0.75的原因是120dpi * 1 /160dpi=0.75。实际上,也就是这么回事。我们下面会仔细的分析。

需要补充一下,通常意义上Android 屏幕的密度,指的是像素密度dpi/ppi,对应于源码中的DisplayMetrics.densityDpi。

为什么引入dp?

Android 引入了dp这一单位,使得不论多大屏幕,多大dpi,显示的效果始终保持一致。

但是根据前面我们提到的px与dp的换算公式px = dp * (dpi / 160),很显然,由于相同分辨率但不同屏幕大小的设备dpi是不同的,导致px和dp的基本不存在一个固定的换算关系,为了方便屏幕适配,Android设置了6个通用的密度,换算px与dp时采取通用密度计算,而非设备实际的密度。

以下为6种通用密度,以及其最小的分辨率

得到上面通用密度之后,我们换算dp与px多了一种简便方式。前面我们提到Android将mdpi作为基准,此时1px = 1dp,又有px = dp * (dpi / 160),所以我们可以很容易的得到以下换算:

还记不记得前面源码中的density属性,实际上DisplayMetrics.density = dpi / 160 ,表示的就是在某个通用密度下dp与px的换算比(1dp/1px的值)

这部分其实和程序员自身已经关系不大了,毕竟参与工作之后这些都是UI人员的活儿了。不过鉴于现在我还只是一枚在校生,还是记下来以免自己遗漏吧。

建议在xhdpi中作图

原因嘛,首先现在主流分辨率是1080p,以及最近流行起来的全面屏18:9,而xhdpi对应720p,向低dpi兼容自然没问题,即便在xxhdpi中显示,也会有个不错的效果。而如果以1920*1080作图,显然图片素材占用的内存很大,而且也会增大应用安装包的大小。

只有一个原则:资源放入对应dpi的文件夹中,Android会机智的加载合适的资源。

以drawable资源为例:

我们平时开发小项目&对UI要求不高时,只使用一套xhdpi的资源就足够了,虽然这可能会导致在hdpi及以下的手机中有些卡顿,因为xhdpi的图片运行在hdpi及以下的手机上会比较吃内存,不过无伤大雅。

而如果不为图片资源犯愁时(有UI人员的支持,就是任性),就可以添加所有dpi的资源。当然,重点还是要满足ldpi:mdpi:hdpi:xhdpi:xxhdpi=3:4:6:8:12的规律。

好像说了不少废话,哈哈,大概就这么多吧。

4. dp的定义原理和dpi,ppi,px,pt,sp之间的区别

dp = dip : device independent pixels(设备独立像素). 不同设备有不同的显示效果,这个和设备硬件有关,一般我们为了支持WVGA、HVGA和QVGA 推荐使用这个,不依赖像素。

px: pixels(像素). 不同设备显示效果相同,一般我们HVGA代表320x480像素,这个用的比较多。

pt: point,是一个标准的长度单位,1pt=1/72英寸,用于印刷业,非常简单易用;

sp: scaled pixels(放大像素). 主要用于字体显示best for textsize。

由此,根据 google 的建议,TextView 的字号最好使用 sp 做单位,而且查看

TextView

的源码可知 Android 默认使用 sp 作为字号单位。

在 Android 中, 1pt 大概等于 2.22sp

以上供参考,如果 UI 能够以 sp 为单位提供设计是最好的,如果设计中没有 sp

的概念,则开发人员也可以通过适当的换算取近似值。

过去,程序员通常以像素为单位设计计算机用户界面。例如,定义一个宽度为300像素的表单字段,列之间的间距为5个像素,图标大小为16×16像素 等。这样处理的问题在于,如果在一个每英寸点数(dpi)更高的新显示器上运行该程序,则用户界面会显得很小。在有些情况下,用户界面可能会小到难以看清 内容。

与分辨率无关的度量单位可以解决这一问题。Android支持下列所有单位。

px(像素):屏幕上的点。

in(英寸):长度单位。

mm(毫米):长度单位。

pt(磅):1/72英寸。

dp(与密度无关的像素):一种基于屏幕密度的抽象单位。在每英寸160点的显示器上,1dp = 1px。

dip:与dp相同,多用于android/ophone示例中。

sp(与刻度无关的像素):与dp类似,但是可以根据用户的字体大小首选项进行缩放。

为了使用户界面能够在现在和将来的显示器类型上正常显示,建议大家始终使用sp作为文字大小的单位,将dip作为其他元素的单位。当然,也可以考虑使用矢量图形,而不是用位图

5. 程序员必须掌握哪些算法

一.基本算法:

枚举. (poj1753,poj2965)

贪心(poj1328,poj2109,poj2586)

递归和分治法.

递推.

构造法.(poj3295)

模拟法.(poj1068,poj2632,poj1573,poj2993,poj2996)

二.图算法:

图的深度优先遍历和广度优先遍历.

最短路径算法(dijkstra,bellman-ford,floyd,heap+dijkstra)
(poj1860,poj3259,poj1062,poj2253,poj1125,poj2240)
最小生成树算法(prim,kruskal)
(poj1789,poj2485,poj1258,poj3026)
拓扑排序 (poj1094)

二分图的最大匹配 (匈牙利算法) (poj3041,poj3020)

最大流的增广路算法(KM算法). (poj1459,poj3436)

三.数据结构.

串 (poj1035,poj3080,poj1936)

排序(快排、归并排(与逆序数有关)、堆排) (poj2388,poj2299)

简单并查集的应用.

哈希表和二分查找等高效查找法(数的Hash,串的Hash)
(poj3349,poj3274,POJ2151,poj1840,poj2002,poj2503)
哈夫曼树(poj3253)



trie树(静态建树、动态建树) (poj2513)

四.简单搜索

深度优先搜索 (poj2488,poj3083,poj3009,poj1321,poj2251)

广度优先搜索(poj3278,poj1426,poj3126,poj3087.poj3414)

简单搜索技巧和剪枝(poj2531,poj1416,poj2676,1129)

五.动态规划

背包问题. (poj1837,poj1276)

型如下表的简单DP(可参考lrj的书 page149):
E[j]=opt{D+w(i,j)} (poj3267,poj1836,poj1260,poj2533)
E[i,j]=opt{D[i-1,j]+xi,D[i,j-1]+yj,D[i-1][j-1]+zij} (最长公共子序列) (poj3176,poj1080,poj1159)
C[i,j]=w[i,j]+opt{C[i,k-1]+C[k,j]}.(最优二分检索树问题)
六.数学

组合数学:
1.加法原理和乘法原理.
2.排列组合.
3.递推关系.
(POJ3252,poj1850,poj1019,poj1942)
数论.
1.素数与整除问题
2.进制位.
3.同余模运算.
(poj2635, poj3292,poj1845,poj2115)
计算方法.
1.二分法求解单调函数相关知识.(poj3273,poj3258,poj1905,poj3122)
七.计算几何学.

几何公式.

叉积和点积的运用(如线段相交的判定,点到线段的距离等). (poj2031,poj1039)

多边型的简单算法(求面积)和相关判定(点在多边型内,多边型是否相交)
(poj1408,poj1584)
凸包. (poj2187,poj1113)

中级(校赛压轴及省赛中等难度):
一.基本算法:

C++的标准模版库的应用. (poj3096,poj3007)

较为复杂的模拟题的训练(poj3393,poj1472,poj3371,poj1027,poj2706)

二.图算法:

差分约束系统的建立和求解. (poj1201,poj2983)

最小费用最大流(poj2516,poj2516,poj2195)

双连通分量(poj2942)

强连通分支及其缩点.(poj2186)

图的割边和割点(poj3352)

最小割模型、网络流规约(poj3308)

三.数据结构.

线段树. (poj2528,poj2828,poj2777,poj2886,poj2750)

静态二叉检索树. (poj2482,poj2352)

树状树组(poj1195,poj3321)

RMQ. (poj3264,poj3368)

并查集的高级应用. (poj1703,2492)

KMP算法. (poj1961,poj2406)

四.搜索

最优化剪枝和可行性剪枝

搜索的技巧和优化 (poj3411,poj1724)

记忆化搜索(poj3373,poj1691)

五.动态规划

较为复杂的动态规划(如动态规划解特别的旅行商TSP问题等)
(poj1191,poj1054,poj3280,poj2029,poj2948,poj1925,poj3034)
记录状态的动态规划. (POJ3254,poj2411,poj1185)

树型动态规划(poj2057,poj1947,poj2486,poj3140)

六.数学

组合数学:
1.容斥原理.
2.抽屉原理.
3.置换群与Polya定理(poj1286,poj2409,poj3270,poj1026).
4.递推关系和母函数.
数学.
1.高斯消元法(poj2947,poj1487, poj2065,poj1166,poj1222)
2.概率问题. (poj3071,poj3440)
3.GCD、扩展的欧几里德(中国剩余定理) (poj3101)
计算方法.
1.0/1分数规划. (poj2976)
2.三分法求解单峰(单谷)的极值.
3.矩阵法(poj3150,poj3422,poj3070)
4.迭代逼近(poj3301)
随机化算法(poj3318,poj2454)
杂题(poj1870,poj3296,poj3286,poj1095)
七.计算几何学.

坐标离散化.

扫描线算法(例如求矩形的面积和周长并,常和线段树或堆一起使用)
(poj1765,poj1177,poj1151,poj3277,poj2280,poj3004)
多边形的内核(半平面交)(poj3130,poj3335)

几何工具的综合应用.(poj1819,poj1066,poj2043,poj3227,poj2165,poj3429)

高级(regional中等难度):
一.基本算法要求:

代码快速写成,精简但不失风格

(poj2525,poj1684,poj1421,poj1048,poj2050,poj3306)

保证正确性和高效性. poj3434

二.图算法:

度限制最小生成树和第K最短路. (poj1639)

最短路,最小生成树,二分图,最大流问题的相关理论(主要是模型建立和求解)
(poj3155, poj2112,poj1966,poj3281,poj1087,poj2289,poj3216,poj2446
最优比率生成树. (poj2728)

最小树形图(poj3164)

次小生成树.

无向图、有向图的最小环

三.数据结构.

trie图的建立和应用. (poj2778)

LCA和RMQ问题(LCA(最近公共祖先问题) 有离线算法(并查集+dfs) 和 在线算法(RMQ+dfs)).(poj1330)
双端队列和它的应用(维护一个单调的队列,常常在动态规划中起到优化状态转移的目的). (poj2823)
左偏树(可合并堆).

后缀树(非常有用的数据结构,也是赛区考题的热点).(poj3415,poj3294)
四.搜索

较麻烦的搜索题目训练(poj1069,poj3322,poj1475,poj1924,poj2049,poj3426)

广搜的状态优化:利用M进制数存储状态、转化为串用hash表判重、按位压缩存储状态、双向广搜、A*算法. (poj1768,poj1184,poj1872,poj1324,poj2046,poj1482)

深搜的优化:尽量用位运算、一定要加剪枝、函数参数尽可能少、层数不易过大、可以考虑双向搜索或者是轮换搜索、IDA*算法. (poj3131,poj2870,poj2286)

五.动态规划

需要用数据结构优化的动态规划.(poj2754,poj3378,poj3017)
四边形不等式理论.

较难的状态DP(poj3133)

六.数学

组合数学.
1.MoBius反演(poj2888,poj2154)
2.偏序关系理论.
博奕论.
1.极大极小过程(poj3317,poj1085)
2.Nim问题.
七.计算几何学.

半平面求交(poj3384,poj2540)

可视图的建立(poj2966)

点集最小圆覆盖.

对踵点(poj2079)

6. 程序员如何选电脑

在商用办公领域,有这样跟一群人十分特殊,每天面对密密麻麻的编程代码,他们就是程序员。程序员们对电脑的性能要求较高,不仅需要处理复杂的运算和变成,更需要胜任多任务处理,一台性能出色的台式电脑是比较好的选择,能够保障复杂工作的稳定完成。那么程序员该如何选配电脑呢?

首先整洁的办公环境能够提高程序员的编程效率。试想,原本就已经十分拥挤的办公桌,如果在桌面堆上一个大型机箱,显然看着就很烦人,可是如果将机箱放置在桌下,使用接口就显得不那么方便了。因此,一个小巧、迷你的台式电脑可以很好解决这个问题,既满足了接口转接的易用性又不影响桌面的整洁程度与空间利用。惠普EliteDesk 800 G2 DM就是一款可以满足程序员开发需求的商用迷你PC。

整洁的办公环境能够提高程序员的编程效率

惠普EliteDesk 800 G2 DM造型相对保守,但是却不给人呆板的感觉。长方体的造型左右侧边完全平坦,惠普EliteDesk 800 G2 DM可以很容易地在桌面平台上竖直摆放,大大节省用户的空间占用。另外,市售产品还搭配有附赠的支撑底座,增强立式摆放的稳定性。

惠普EliteDesk 800 G2 DM可以很容易地在桌面平台上竖直摆放,大大节省用户的空间占用

惠普EliteDesk 800 G2 DM整机是一个标准的矮个子长方体,厚度不大,俯仰截面接近正方形,长宽比较小,不像书本更像是过去的一些小型收音机。整机材质采取钢制外壳,手指弹上去清脆作响,强度不是问题,十分结实,只有前面板采取了塑料材质,其前面板散热孔设计颇有一种旧时的情怀。

整机材质采取钢制外壳不像书本更像是过去的一些小型收音机

其次扩展性一定要强,程序员在工作时还需要转接各类基于USB口或者其他接口的设备。而作为一款商用迷你机设备,外部扩展能力也是十分重要的,迷你机身设计并没有给惠普EliteDesk 800 G2 DM的接口配置带来影响。

惠普EliteDesk 800 G2 DM的接口配置

惠普EliteDesk 800 G2 DM配备了2个USB2.0、8个USB3.0接口、耳机/麦克风接口、2个DP接口、VGA接口以及RJ45网线接口;十个USB接口可以充分满足程序员的多设备调试需求,三个视频输出接口可以轻松转接多个显示屏,无疑是提高工作效率的有效手段。

惠普EliteDesk 800 G2 DM的前面板和上表面为整体可拆卸式外壳设计

另外,惠普EliteDesk 800 G2 DM的前面板和上表面为整体可拆卸式外壳设计,只用一颗螺丝在后方负责固定,拆解起来较为简便。由前面板和上表面连接而成的顶盖,只需轻轻滑动即可抽离,内部一览无余,值得一提的是,后方固定用的螺丝并不能完全拧下,是惠普为了防止用户弄丢螺丝做的设计。

既然是程序开发的硬件需求,足够强劲的性能表现是最为重要的,这直接影响到多任务处理的效率。以惠普EliteDesk 800 G2 DM为例,该机配备了英特尔第六代酷睿i7-6700四核vPRO处理器并且搭配DDR4 2133MHz内存。酷睿i7-6700采用四核设计、8MB三级缓存、3.4GHz主频支持睿频至4.0GHz、工作功率65W,这颗处理器不仅能提供强劲的性能输出,并且还能有良好的稳定性,vPRO技术还能扩展不少企业功能。

配备英特尔第六代酷睿i7-6700四核vPRO处理器

程序设计过程中需要大量的编程运算,酷睿i7-6700可以提供长时间稳定且高效的高性能输出。处理器性能方面我们采用三款同系列测试软件CINEBENCH对其性能测试,得出的结果仅供参考。首先是CINEBENCH R10的测试结果,该处理器获得单核7928分,多核31362分;在CINEBENCH R11.5测试中,该处理器多核心获得8.87pts,单核心1.92pts;最后在CINEBENCH R15测试中,该处理器多核心获得802cb,单核心169cb。处理器单项测试结果表明该处理器定位于桌面平台处理器高端型号。

CINEBENCH R10的测试结果

CINEBENCH R11.5的测试结果

CINEBENCH R15的测试结果

除此之外,惠普EliteDesk 800 G2 DM搭载的第六代酷睿支持DDR4 2133MHz内存,相对过去的DDR3内存在频率上有着十足的提升,频率更高意味着高负荷处理一些文件时能有更好的性能输出,可以进一步提升运算效率。另外,配备SSD固态硬盘更是为响应速度加足了马力,近年来机械硬盘普遍拖累了整机性能表现,而SSD固态硬盘拥有高速的读写速度,高性能酷睿处理器搭配高速率SSD可以满足中高强度的开发需求。

7. DPI和PPI

不论是DPI还是PPI,实际都是一种换算的概念,即将图片承载的信息换算为现实中的图片(即人眼能实际看到的图像)。DPI和PPI的区别在于换算的途径不同,DPI面向的是印刷受体,而PPI面向的是荧幕。

PPI是英文Pixels Per Inch的缩写,意为像素每英寸。英寸是常用的长度单位,大约相当于2.54厘米。而像素是专用于荧幕的概念,指的是荧幕可以解析的最小的点。因此,PPI值得是像素在荧幕上的密度,PPI越高图像就越清晰

举例来说,如果电脑屏幕是2K分辨率,即1920×1080像素,它的图像宽为1920像素。而如果这个电脑屏幕的物理宽度是19.2英寸,电脑屏幕是分辨率就是1920/19.2=100PPI。

DPI是英文Dots Per Inch的缩写,意为点每英寸。应粗你还是那个英寸,但是点的意义有很多。一般来讲,你可以把Dot理解为取样点,即物理设备可以解析的最小单位。在印刷时,它就可以作为印刷网点,而在鼠标等电子设备上,可以理解为最小操作阈值(即设备会把多么远的两个点当作一个点来处理)。

我们仍然拿1920×1080像素的图片来举例子,如果印刷设备的解析能力刚好是100DPI,而且你要印制的纸张尺寸刚好是19.2英寸,那么印刷设备就可以刚好把一个像素作为一个取样点,印刷完成后图片的保真度是百分之百(也就是图片所有的视觉信息都被印刷出来了)。在大多数情况下,这几个数值都不那么整好,因此保真度会产生损失。

1.在条件允许的情况下,图片分辨率越高越好 我们可能不会有精力去关心图片信息量的DPI是多少,印刷设备的DPI又是多少这种细节的问题。但有一点是可以确定的,那就是图片只要足够大,印刷就会清晰。

2.如果有可能,使用准确的数值 许多软件可以帮助你了解图片实际尺寸下的PPI,比如使用Photoshop,在300PPI下创建A4的文件(尺寸21×29.7厘米,对应分辨率2480×3508像素)并做出图片,那么大多数情况下都可以完美印刷。

正如前文所述,大多印刷设备的解析能力是300DPI,因此在该图片的信息量下,1个像素刚好对应1个点,甚至不需要栅格处理。而如果你强行使用400PPI来创建A4尺寸的文件,拿到300DPI的设备上会被栅格,说不定还不如300DPI的质量好(毕竟是有损处理,但这种差别未必能看得出来)。

下图是苹果官方对iPhone 机型的介绍:

拿iPhone7 Plus来说:

屏幕尺寸:5.5英寸

手机分辨率(像素):1920 (高)x 1080(宽)

PPI:401

屏幕尺寸:表示手机屏幕对角线的长度,单位是英寸。1英寸(inch)=2.54厘米(cm)

手机分辨率:分辨率可以从显示分辨率与图像分辨率两个方向来分类。

显示分辨率(屏幕分辨率):屏幕 图像 的精密度,是指 显示器 所能显示的 像素 有多少。由于屏幕上的点、线和面都是由像素组成的,显示器可显示的像素越多,画面就越 精细 ,同样的屏幕区域内能显示的信息也越多。

图像分辨率:单位英寸中所包含的像素点数,其定义更趋近于分辨率本身的定义。

分辨率的单位:(dpi 点每英寸 )、lpi(线每英寸)和ppi( 像素每英寸 )。但只有lpi是描述光学分辨率的尺度的。虽然dpi和ppi也属于分辨率范畴内的单位,但是他们的含义与lpi不同。而且lpi与dpi无法换算,只能凭经验估算。ppi和dpi经常都会出现混用现象。但是他们所用的领域也存在区别。从技术角度说,“像素”只存在于电脑显示领域,而“点”只出现于打印或印刷领域。

ppi:Pixels Per Inch,屏幕像素密度,每英寸屏幕所拥有的像素数,在电脑显示领域使用。

dpi:Dots Per Inch,每英寸长度上的点数,在打印领域使用。

屏幕像素密度,分辨率,屏幕尺寸的关系

所以美工使用PS作图的大小为手机分辨率的大小。

如需要设计适配iPhone7的手机,我们使用1334 x 750px大小

但有一点是特殊的,就是iPhone6(s) plus、iPhone7 plus,我们需要使用2208 x 1242px大小,

原因:

ppi为326的手机,使用的为@2x的素材,对于ppi是401的手机,理论上苹果应该用401/326 * @[email protected]的素材。但是这个奇葩的比例对开发者而言很难切图。所以苹果为方便开发者用的是@3x的素材,然后再缩放到@2.46x上,实际上是缩放到2.46/3=83%。实际上苹果选取了一个接近比例的87%。

这样算下来,物理分辨率和虚拟分比率的比例是87%,也就是1920/0.87=2208,1080/0.87=1242.

好处就是开发者更方便,比如准备素材时,字号可以直接调成3x的。

概述

前段时间看了小米8的发布会,其中屏幕参数是如下介绍的:

当时我就在想这都是怎么算出来的,虽然我知道 PPI 是指屏幕每一英寸上包含的像素点,但是稍微往深一想我发现我对这些参数真的很迷茫,好奇心驱使我做了些调查。

像素,英文为 Pixel ,是我们日常最熟悉不过的了,但是深入进去会发现其蕴含的知识量是巨大的,此篇对于像素话题也只是浅尝辄止,抛砖引玉。

讨论像素需要分不同的场景: 1. 数字图像 我们程序员日常工作中接触并讨论的像素大多是指这个范畴。

光栅图片(Bitmap)是我们日常接触最多的,例如 jpg,jpeg,png,gif,bmp等等,另一种比较常见的就是矢量图了。 光栅图片是由一个一个像素组成的,那么像素包含哪些信息?有物理尺寸吗?

每个像素由颜色信息组成,有的还包含一个透明度信息。因为可以通过三原色 Red , Blue , Green 来混合出很多种颜色,所以一个像素就可以使用存储这三种颜色的一个数据结构表示。一个像素占用内存的大小,与其使用多少位来表示这些颜色有关,例如最简单的像素只有一个 bit ,那么它只能表示两个状态,0或者1,对应到图像上也就是黑白。当一个像素达到24 bit 的时候,RGB每个通道占8位,可以组合出来的颜色已经有1677万色(256 256 256=16,777,216)种了,而人类眼睛可以分辨的颜色也只有大概1000多万种,此时就是真彩色了。当然还有32位真彩色,感兴趣的可以去研究。

图片来自 维基网络

那么通过以上的介绍,我们可以得出结论,此处的像素没有物理尺寸,仅仅是一些数据,只有将其显示在物理设备上才会存在物理尺寸。

可以通过下图感受一下

图片来源

讨论分辨率仍然需要分讨论场景 1. 数字图像 此时分辨率是用来描述图片的像素信息的,比如我们说一张图片的分辨率是1280 720,那么仅仅是说明这张图片是由1280个像素 720个像素组成的。如下图所示,至于这张图片的尺寸有多大,清晰还是模糊,这取决于它自身的存储格式以及用来显示它的设备。

2. 硬件显示设备 是指这块屏幕所包含的像素(这个像素是物理上的,前面我们已经讨论过了)。例如小米8的屏幕分辨率为2248x1080,说明这块屏幕包含了这么多物理像素。

那么图片的分辨率与屏幕的分别率是什么关系呢?这需要清楚了 PPI 后才可以回答这个问题。

DPI 是印刷业使用的单位,其表示的是打印纸上每一英寸包含的墨点数量,而 PPI 是电子屏幕上每一英寸上包含的可寻址物理物理显示单元。其中英寸是西方惯用长度单位,等于2.54厘米。这两个概念之所以如此容易混淆,就是因为一些软件提供商做的孽,例如Microsoft,Adobe,Apple 等等,他们经常将这两个概念互换使用。

PPI : Pixels Per Inch, 每一英寸上包含的像素个数。 这个值越高,屏幕的显示能力越强,例如小米8 PPI的计算方式如下图所示

可见小米8的 PPI 是401.6,而其官方宣称为402,估计是四舍五入了,不过不知道半个像素怎么处理,知道的可以告诉我一下。

DPI : Dots Per Inch, 每一英寸上包含的点个数。 与PPI计算方式一样,只是应用的领域不同,这个用在印刷业的。

至此我们可以回答图片的分辨率与屏幕的分辨率的关系了,以小米8为例,按照 图片比例全屏 显示某一张图片: 第一:当将一张1080 2248像素的图片显示在Mi8上时,屏幕上的每一个物理像素对应一个图片像素,可以完美显示。 第二:当将一张2000 2248像素的图片显示在Mi8上时,Mi8的屏幕在宽度上是无法显示的,所以显卡会将图片光栅化,通过一定的算法将2000个像素减少到1080个像素,由于是从多到少的处理,所以图片是清晰的。 第三:当将一张720*1280像素的图片显示在Mi8上时,显卡会将图片光栅化,将图片以其中一边为标准拉伸,图片会变模糊。

Pt :汉语翻译为 ,是一个物理尺寸,长度为1/72 英寸,在概念上Pt与Px毛关系也没有,但是在 photoshop 中就有关系了。 photoshop 中的pt却是一个相对单位(这帮二货各种混用)

换算公式: 1pt= (DPI / 72) px

dp : Density-independent Pixels, 这个是Android基于物理设备的 ppi 抽象出来的一个单位。它是以 160dpi 的屏幕为基准定义的,在 160dpi 的屏幕的屏幕上 1dp=1px ,那么我们就可以得出其

换算公式: 1dp=(屏幕ppi/ 160)px

目前Android系统的屏幕分类如下表 |密度分类| 屏幕密度 | |--|--| |ldpi |120dpi | |mdpi |160dpi | |hdpi |240dpi | |xhdpi |320dpi | |xxhdpi |480dpi | |xxxhdpi |640dpi |

sp : Scale-independent Pixels,其与dp基本一样,也是像素无关的,但是是用在描述字体的大小上。其尺寸会同时相应屏幕密度以及用户对字体的偏好设置。 例如:在手机的字体设置为默认大小时,使用 dp sp 描述字体的大小是一样的,如下图

但是当我们改变了手机的字体默认设置的字号后, dp 描述的字体大小没有变化,但是 sp 描述的字体大小却相应的发生了变化,如下图。

除此之外 dp sp 再无差异,一般建议字体使用 sp 作为单位。

dip 就是 dp 互为别名,没有任何区别,其与 px 关系见上文。

以上就是关于显示接触GUI开发的程序员应该了解的,本来以为很简单,但是调查后发现再往深研究我将会陷入泥潭无法自拔。同时我也感受到,人类社会发展到目前的水平,任何一个门类的知识都足以让一个人投入终身的时间去研究,那我们程序员除了赚钱养家是不是应该找个自己感兴趣方向忠贞不渝的投入一生业余精力去尝试研究一番呢?在此我觉得我很挫败,突然发现自己这么大年纪了竟然没有爱好,如果爱好美女这个不算的话。。。!

我们的原图是一份长宽都是1800像素的图片。

这张图片长宽都是1800像素 ,对它自己而言,DPI和PPI没有意义。
它的分辨率参数,仅仅是1800像素而已。

假设我们的所有印刷机、打印机、喷绘机,在原尺寸下都将1像素映射为1个点(即1Px/Dots),可以进行下面这些计算。

如果我们使用300DPI的印刷机,原尺寸打印这张图,那么它的长宽为:
1800 Px / (1Px/Dots) / 300 DPI = 6 in 即长宽都是6英寸(15.24厘米)。

如果我们使用220DPI的打印机, 原尺寸打印这张图,那么它的长宽为:
1800 Px / (1Px/Dots) / 220 DPI ≈ 8.19 in 即长宽都是8.19英寸(20.8厘米)。

如果我们使用72DPI的喷绘机, 原尺寸打印这张图,那么它的长宽为:
1800 Px / (1Px/Dots) / 72 DPI = 25 in 即长宽都是25英寸(63.5厘米)。

使用81PPI的一般显示器,原尺寸显示这张图, 那么它的长宽为:
1800 Px / 81 PPI ≈ 22.2 in 即长宽都是22.2英寸(56.4厘米)。

显示器的PPI 我们假设显示器是方形像素,那么显示器的PPI是由它的分辨率和长宽共同决定的。

即显示器的横向PPI=显示器的横向分辨率(Px)/显示器的宽度(in)。

我们常说的显示器的英寸数,是其对角线的长度。 对于16:9的显示器来说,PPI可以这样计算:
PPI = sqrt { (像素宽 * 像素高) / [16 * 9 * 英寸数^2 / (16^2 + 9^2)] }

举例来说,1920*1080像素的24寸显示器,PPI就是:
PPI = sqrt { (1920 * 1080) / [16 * 9 * 24^2 / (16^2 + 9^2)] } ≈ 91.7878

下面的表格计算了常见显示器尺寸的PPI,你可以用这个公式检验:

阅读全文

与程序员dp相关的资料

热点内容
安卓手机的表格里怎么打勾 浏览:407
阿里云服务器有网络安全服务吗 浏览:966
超解压兔子视频 浏览:22
单片机怎么测负脉冲 浏览:172
魅族备份的app在哪里 浏览:738
java倒三角打印 浏览:112
通达信回封板主图源码 浏览:44
战地什么服务器 浏览:299
安卓为什么老是闪退怎么办 浏览:803
乐高机器人的编程软件下载 浏览:223
工作中怎么使用加密狗 浏览:735
云服务器的后台找不到 浏览:98
php逐行写入文件 浏览:912
javaoracleweb 浏览:440
京东加密码怎么弄 浏览:467
单片机程序员培训 浏览:992
PHP商城源代码csdn 浏览:636
怎么把电脑里文件夹挪出来 浏览:693
java流程处理 浏览:685
ftp创建本地文件夹 浏览:660