1.1 CPU 占用率html
http://www.javashuo.com/article/p-qyvyqoiq-ce.html算法
1.2 中国象棋将帅数组
https://blog.csdn.net/kabini/article/details/2256421
https://blog.csdn.net/ltyqljhwcm/article/details/52203578服务器
1.3 烙饼排序函数
https://blog.csdn.net/jiyangsb/article/details/45970381优化
1.4 书店促销.net
书店促销活动,某套书一共有五卷。假设每一卷单独销售均需8欧元,多买则有折扣,具体折扣以下:线程
2 | 5% |
3 | 10% |
4 | 20% |
5 | 25% |
设计算法,计算出读者购买一批书的最低价格。设计
可使用动态规划算法或优化的贪心算法。htm
https://blog.csdn.net/eeelan/article/details/76083174
1.5 快速找出故障机器
有不少服务器存储数据,假设一个机器仅存储一个标号为ID的记录,假设机器总量在10亿如下且ID是小于10亿的整数,假设每份数据保存两个备份,这样就有两个机器存储了一样的数据。
问题:
1.假设在某个时间获得一个数据文件ID的列表,是否能快速地找出表中仅出现一次的ID?即快速找出出现故障的机器存储的数据ID。
2.若是有两台机器出现故障呢?(假设存储同一份数据的两台机器不会同时出现故障,即列表中缺乏的是两个不等的ID
问题转化:
有不少的ID,其中只有一个ID出现的次数小于2,其余正常ID出现的次数都等于2,问如何找到这个次数为1的ID.
解法一:暴力解决
方法:遍历列表,利用一个map记下每次出现的ID和出现次数+1,遍历完毕以后,出现次数小于2的ID就是咱们想要的结果。
时间复杂度:O(N)
空间复杂度:O(N)
缺点:当记录N多达几G甚至几十G时,空间复杂度将会成为瓶颈。
解法二:两次即删
方法:遍历列表,利用变长数组记录每一个ID,每次遇到一个ID,就向变长数组中增长一个元素,若是这个ID出现的次数为2,那么就从变长数组中删除这个ID, 最后变长数组中剩下的ID就是咱们寻找的ID。
时间复杂度:O(N)
空间复杂度:最好O(1),最坏O(N)
解法三:异或运算
思路:摒弃遍历列表技术方式
目标:把空间复杂度下降到常数甚至为1的级别,即便用一个变量来记录遍历列表的结果
构造函数:
x(i) = f(List[0], List[1], List[2], ... , List[i])
即:这个变量是已经遍历过的列表元素的函数
该函数须要知足的条件:x(N) = ID_LOST
运算:异或
性质:X 异或 X = 0, X 异或 0 = X, 异或操做知足交换率和结合律
方法:因此的ID的异或值就等于这个仅出现一次的ID。
时间复杂度:O(N)
空间复杂度:O(1)
解法四:寻找不变量
方法:全部ID的和是不变的,因此用全部ID的和减去现有ID的和即得丢失的ID。
时间复杂度:O(N)
空间复杂度:O(1)
缺点:不适用于丢失多个ID的状况
问题进阶一:当有两个ID的机器一块儿出现故障,肯定出现故障的机器
若是缺乏的两个ID不相同
解法:异或运算
对全部ID进行异或运算,结果为a(不等于0)
肯定a的某一个为1的二进制位置b
将全部ID分为两组:二进制位置b为1的为一组A,二进制位置为0的为一组B
对AB两组分别进行异或运算,获得两个不为0的数字,即为丢失的两个ID
若是不能肯定缺乏的两个ID是否相同
解法一:
由于已知丢失两个数是相同的,因此经过上面的解法四能够获得 x + y = a, x * 2 = a, x = a/2
固然,这种方法是创建在已知两个数是相同的前提下的。
解法二:(通用解法,对丢失N个数的状况一样适用)
若是不知道两个数是否相同,能够经过创建方程组来解决
解法一已经给出了一个方程组: x+y=a
那么再计算丢失先后的全部ID的平方和,进行相减,能够又获得一个方程: x^2 + y^2 = b
联立方程组便可求解。
问题进阶二:当有多个ID的机器一块儿出现故障,肯定出现故障的机器
解法一:
参考问题进阶一解法二。
缺点:当N过大时,N个方程组不易求解。
解法二:
参考解法二,遍历+计数+两次即删。
参考:
https://blog.csdn.net/zs634134578/article/details/18046317
http://blog.csdn.net/insistgogo/article/details/7687936
1.6 饮料供应
水房能容纳饮料的总量是V,有一批饮料,每种饮料单个容量都是2的方幂,每种饮料信息以下:(Si,Vi,Ci,Hi)分别对应(名字,容量,满意度),求在知足总容量等于V的状况下,求满意度的最大值。
分析:
一、动态规划解法
没有悬念,优化问题就用动态规划、贪心算法、分支限界轮番上阵就行了。设Opt(V’,i)表示从i到n-1种饮料中,Ci为第i种饮料可能的最大数量,算出总量为V’的方案中满意度之和的最大值。那么递归式就应该是:
Opt(V’,i)=max{ k * Hi+Opt(V’-Vi * k,i+1)}(k=0,1,2…,Ci,i=0,1,2…,n-1)
二、动态规划法的变形:备忘录法
三、贪心算法
书中的贪心解法似曾相识,把信息按照饮料的容量排序(其中设咱们有n0种容量为20的饮料)
而后按照下面的顺序进行贪心选择:
(1) 饮料总量为1,从容量为20的饮料中选出快乐指数最大的。
(2) 饮料总量为2,从容量为21的饮料中选出快乐指数最大的(设为H1),与容量为20的饮料中快乐指数最大的(设为H0),比较H1和2* H0,取出其中最大者为当前最佳选择
(3) 继续进行下去,直到求出Opt(V,0)
参考:
https://blog.csdn.net/kabini/article/details/2311946
1.7 光影切割
在一个平面内有一个矩形区域,直线穿过矩形能够将其分割为不一样的区域,且在这个平面中不存在三条直线相交一点的状况。求当有N条直线穿过矩形时,它被分割为多少个区域?
解法一:
平面倍划分红多少块的问题能够转化为直线的交点有多少个的问题。
两条直线-->一个交点-->空间分红4个部分
三条直线-->两个交点-->空间分红6个部分
三条直线-->三个交点-->空间分红7个部分
每增长一条直线,若是增长M个交点,那么这条直线被新增长的M个交点,分红M+1段。每一段直线会将原来一块区域分红两块,所以,新增长M+1块新区域。
若是总共有N条直线,M个交点,那么区域的数目为N+M+1。如何证实?将N条直线逐一投影到坐标区间上,假设第K条直线与以前的K-1条直线的焦点为Nk个,那么它使得区间内的区域块增长Nk+1个。则N条直线投影完毕后,全部区域块的数目为:
1+sigma(Nk+1)(1-->n)=1+N+sigma(Nk)(1-->n)=1+N+M
所以,求出全部直线两两相交的交点,而后再查找落在区间内的交点,就能够计算出划分的区域块数。将全部交点存储于数组Intersect中,而后计算。这样,算法的复杂度就转化为查找交点数组的问题了。
数组初始化,即计算全部交点,时间复杂度为O(N^2)。每次查询的时间复杂度为O(M)。
若是在初始化后对全部交点按X轴坐标排序,则复杂度为O(N^2+M*logM),以后进行二分查找,每次查找的时间复杂度为O(logM)。
解法二:
一个交点的状况,两条直线与左边界的交点顺序为(a,b),与右边界的交点顺序为(b,a),顺序反过来了。若是没有交点,则顺序不变。
区域内的交点数目等于一个边界上交点顺序相对另外一个边界交点顺序的逆序总数(利用到条件“没有三条直线相交于一个点”)。
问题转化为求一个N个元素数组的逆序数。
求解逆序数的直接方法时间复杂度为O(N^2),若用分治策略,可降为O(N*logN)。分治思想以下:求前N/2个元素的逆序数,再求后N/2个元素的逆序数,最后在排序过程当中合并先后两部分之间的逆序数。
参考:
https://blog.csdn.net/lonelycatcher/article/details/7907333
1.8 电梯调度
全部的员工均在1楼进电梯的时候,选择所要到达的楼层。而后计算出停靠的楼层i,当到达楼层i的时候,电梯中止。全部人走出电梯,步行到所在的楼层中。求全部人爬的楼层数目和的最小值。
解法一:
使用简单的方法,直接将楼层从1到n开始遍历
sum(person[i] * |i - j| ) 此表达式为一个双重循环,i与j均为1-n的循环。
j下标表示电梯停靠的楼层。
person数组表示,对应i层的下电梯的人数。此算法负责度为o(n*n)
对应的j是上述和为最小的一层即为所求。 上面的算法复杂度为o(n)
解法2:
下面考虑一个简单的算法,使其复杂度达到o(n)
考虑假如电梯停靠在某一楼层i处,假设在i处下楼的客人为N2,
在i以上楼层的客人数目为N3 ,在i一下楼层的客人数目为N1。
且将电梯在i层中止时,所有人员的路程之和记为T。
那么加入电梯在i-1层停的话,则原来i层之上的人须要多爬一层,即增长了N3
第i层的人须要多爬一层,则结果增长了N2, i层之下的人则少爬了一层,结果减去N1
因此第i-1层的结果为 T - N1 + N2 + N3 。即结果能够即为 T -(N1 - N2 - N3)
下面考虑在i+1层的结果,若电梯在i+1层中止的话,原来i层之上的客户都会少爬一层,
则结果减小N3 ,而i层之下的人员则都会多爬一层即增长了N1 ,第i层的人员都会多爬一层
即为增长了N2 。则结果为 T + N1 + N2 - N3
综上咱们得出,
(1)若N1 > N2 + N3的时候, 咱们在第i-1层 选择电梯中止最好。
(2)若N1 + N2 < N3的时候, 咱们选择在第i+1层中止电梯最好。
下面咱们能够先计算出来当i=1时候的T ,而后判断是否须要在i+1层中止,如果i+1层的花费
大于i层,则咱们能够继续计算,不然退出。
解法三:
假设只有两我的,一个去9层,一个去2层,那么无论电梯停在2至9层中间的任何楼层,两我的的总花费都是7.就好比在数轴上点2和点9中间的任何点距离2和9的距离以后都是7。那么停在哪都无所谓了。接着咱们扩展开来,假设有N我的,他们的目标楼层分别是2,3,3,4,5,5,5,7,7,8,9。按咱们的想法,对于两端的(2,9)电梯只要停在他们之间都同样。同理对于(3,8)电梯只要停在他们中间都同样……。最终电梯只要停在中间那个数便可。也就是中位数。原来弄半天只需求出中位数便可啊。若是N是偶数个的话,停在中间那两个数任何一个均可以的。欢迎你们对个人解法拍砖。代码就不用了吧。
扩展1:
若是往上爬楼梯比较累,往下走较容易,假设往上走一层耗费k单位的能量,往下走一层只耗费1单位的能量。
扩展2:
M层电梯K个停靠层,可将最终问题分红两种状况:1,第M层为一个停靠层次;2,第M层不做为停靠层次。第一种状况经过动态规划解出,第二种状况运用第一种状况子问题数据能够解出。
解法:
用数组A[1]、A[2]、...A[M]分别记录需到电梯1~M层的乘客人数;Cost[i][j]记录i层到j层之间,只有第i和第j两层能够停靠,乘客(i和j层之间全部乘客)须要爬的电梯的最少层数;F[i][j]表示1~i层电梯之间,j个楼层停靠,且第i层必须是一个停靠层的的最优解;所求解为S[M][K],即电梯总共M个层,有K个停靠层,使全部乘客全部乘客须要爬的电梯层数最少,该选择哪些层停靠?最少是多少层?
状态方程为:
S[i][j] = min{F[i][j], min{F[i-t][j] + A[i]*t + A[i-1]*(t-1) + A[i-2]*(t-2)...A[i-t+1]*1} (1 <= t <= i-j) }
解释:最外层min{}中前一部分表示第i层做为停靠层的状况,后一部分表示第i层不做为停靠层的状况
1.9 见面会安排
有n个学生参加见面会,分别对m个研究组中的若干个感兴趣,为了知足全部学生的要求,每一个学生都能参加本身感兴趣的见面会,若是每一个见面会的时间为t,如何安排才能使得全部见面会的总时间最短?
分析:
先创建模型,将m个见面会当作点,若是有一位同窗同时对两个小组感兴趣,就在这两个小组对应的点间加上一条边。不难看出,构造出这样一幅图后,问题转化成求图的最少着色问题。
参考:
https://blog.csdn.net/chdhust/article/details/8333567
1.10 双线程高效下载
1.11-1.13 Nim 游戏
1.14 连连看游戏
1.15 数独游戏
解法一:广度优先搜索。
解法二:先填满中间矩阵,其余区域经过矩阵置换求出。
1.16 24点游戏
解法一:穷举法
解法二:分治法
1.17 俄罗斯方块游戏
1.18 扫雷游戏