海清's profileCockhorse BlogPhotosBlogListsMore ![]() | Help |
|
|
February 28 矩阵经典例题给定一个有向图,问从A点恰好走k步(允许重复经过边)到达B点的方案数mod p的值 February 01 DP 决策优化我把N个白色(2<=N<=10000)的小球摆成一排。现在,我想把其中一些小球涂黑,使得每M个连续的小球中至少有两个球是黑色的(2<=M<=100)。我已知给第i个球染色需要花费Ci个单位的染料。我想知道,至少需要花多少染料才能满足我的要求。 f[i,j]=min{f[j,k]}+w[i] f[i+1,j]=min{f[j,k]}}+w[i+1] (决策一样 所以可以优化) => 当i=j+1时 f[i,j]=min{f[j,k]}+w[i] 当i>j+1时 f[i,j]=f[i-1,j]-w[i-1]+w[i] 二维转三维给一个无向图,每条边有个权值,你可以让任何一条边权值减半,这样的操作可以做10次,每条边可以减多次,求减了之后的单元最短路。要求与一般的求最短路方法同时间复杂度的方法。 把这个图分成10层,边成一个三维图,每层的边权值都不变,第i层到第i+1层的边减半一次,第i层到第i+2层的边减半两次....... 最后求的即是从第一层的起始点到第10层的终点的一条单元最短路。 线段树1.一段数,每次给一个区间涂色,询问某个数的染色。 分析:记录涂的颜色和涂色的序号,询问一个数时,从下到上取序号最大的染色。 2.一颗二叉树,每次改某个节点的值,询问某棵子树的节点和。 分析:不能直接在二叉树上做,因为二叉树易退化。 先前序遍历一次,每个节点对应一个数(前序遍历的序号),每棵子树表示一个区间(前序遍历中该子树的最小标号到最大标号),即可用线段树解决 3.一段数,每次改一个数,询问某个区间的最大子序列和。 分析:线段树每个位置记录三个东西:最大子序列和、左边开始最大和、右边开始最大和 January 31 科学的双向链表顺序给出N(1<=N<=50000)个数A1,A2,A3,...,An,其中第i个数的“最小波动值”定义为它与在它前面的数中所能产生的最小差值,即Ai的最小波动值为Min{ |Aj-Ai|, j<i }。我们规定,A1的最小波动值就是A1。 编写程序求出所有数的最小波动值的总和。 1.动态树 2.线段树 3.排序+二分查找 *4.排序+双向链表 先排序,用双向链表记录新序列并且原序列每个数用指针指向新序列对应的位置. 在原序列中从右往左枚举,当前数的最小差值就等于在新序列中与左右两个相邻数的差值的最小值,然后在双向链表中把这个数删掉(因为从右往左做,每次都会删掉,所以剩下的数全是它左边的,则相邻的一定是可行的且是最优的),所以用双向链表就可以在O(n)完成.当然,排序需要O(nlogn). 博弈论P 必胜 N 必败 P->只要有一个N N->所有都是P 一般地:先写个DP(可行性转移),再来找规律 1.欧几里德游戏:给一个数,每次可以减去小于它的一个约数,不能再减了(即拿到一了)就算输. 偶数为必胜,奇数为必败. 2.分巧克力:一个n*m的巧克力块,可以任意分成边长均为整数的两个小巧可力,如果不能再分了(即拿到1*1的了)就算输. 当m=n时必败 3.猫老大取数(2^n):给一个数n,每次可以减去2^k(k属于非负整数),如果把这个数减成0了就算赢. 3的倍数必败 4.Lim取火柴:有n堆火柴,第i堆有ai根火柴,每次可以在任何一堆里取走任何数量的火柴,先取完者算赢. 把每一堆的火柴数全部xor,若为0则必败 January 30 二分答案1.收入计划 问题描述 输入数据 输出数据 输入样例 输出样例 样例说明 100 400 300 100 500 101 400 每一天的薪水
2.架设电话线 问题描述 输入数据 输出数据 输入样例 输出样例 样例说明
3.旅行路线 问题描述 输入数据 输出数据 样例输入 样例输出 样例说明
4.猜数游戏 问题描述 输入数据 输出数据 样例输入 样例输出 样例说明
分析: 1.二分工资最大值,再用贪心方法(从左往右能去就去)判断是否可行. 2.二分自己要赋的最大值x,把所有大于x的边标记,则需判断经过最少标记是否小于k. 求最少经过标记数:把标记的边赋为1,没标记的边赋为0,求出起点到终点的最短路即可. 3.由于 min(a/b,c/d)<=(a+c)/(b+d)<=max(a/b,c/d) (证明略) 那么最优的回路肯定不会经过同一个点两次,即所求回路为简单回路. 对于某个环: t 乐趣 t 时间 二分x , s/t>=x -> t*x-s<=0 , 即判断是否有负环即可 4.对于每个数,赋为所有覆盖它区间的最大值,再看是否满足每个区间即可. 离散化n个数即可变成q个数,再二分问题数O(logp),然后赋值和判断O(p),总时间复杂度O(plogp) 树规1.树的划分 给定一棵树,为了分离出一棵有K个结点的子树,最少需要删掉多少条边 将其转为二叉树 2.07年m67生日邀请赛 wolf 给出一个图,每条边上都有权值,除一号节点外,其它节点上都有A、C两种不同的权值,选取C权值和不超过K的若干顶点,使这些顶点及它们到1号结点的最短路上经过的所有其它顶点的A权值和最大,有多条最短路可选时总是选择前往编号小的结点 由所有的最短路构成了一棵树,然后多叉转二叉,f[i,j]表示在这棵二叉树上的子树花费j个材料的最大值 (1). 自己把材料用了; 状态O(nk)个,决策为O(k),时间复杂度O(nk^2) 3.IOI2005 Day2 Rivers 一棵树n个节点,根结点已有个工厂,需要再设k个工厂,每个节点有个货物数,每条边有权值,每个节点的货物都送到上面的最近的设了货物的节点. 算法O(n^2k^2) (多叉转二叉) j表示i上面最近的工厂 k表示一共设的工厂数 f[i,j,k]= 不设工程 min{f[i.left,j,k']+f[i.right,j,k-k']+w[i]*d[i,j]} 设工程 min{f[i.left,i,k']+f[i.right,j,k-k'-1]} DP经典问题1.定义鹰蛋的坚硬程度E为:从第E层楼及以下楼层落下时不会碎,但从第E+1层楼及以上楼层向下落时会摔碎。 任务:不断在一幢N层大楼内向下扔鹰蛋来确定坚硬程度E,可供使用的鹰蛋共有M个,假设所有的鹰蛋都具有相同的坚硬度,求最坏情况下确定E所需要的最少次数。 f[i,j]=min{max{f[i-1,k-1],f[i,j-k]}}+1 O(mn^2) f[i-1,k-1]为非减的,f[i,j-k]为非增的,则min取的是两个"函数"的交点 可以用二分的方法找这个"交点" , 则优化到 O(mnlogn) 2.NOI2005 adv1900 (队列优化) 给定一个带障碍物的MxN阵列,给出K次船体倾斜的方向及其时间范围,钢琴随船体倾斜方向滑行,钢琴不能撞到障碍物或滑出边界,天使可在任意时刻使钢琴暂时静止,求钢琴最长的滑行距离 不妨设k方向为右 f[(i,j),k]=max{f[(i,j'),k-1]+j-j'} => f[(i,j),k]=max{f[(i,j'),k-1]-j'}+j 当j增加,j'范围是增加或不变的,所以直接维护一个长度小于等于m的递减队列即可 January 29 DP优化(单调性)1.序列A1,A2,....,AN,一次操作是将某个数增一或减一,用最少的操作次数将原序列改为递增序列 f[i,j]=min{f[i-1,k]}+|a[i]-j| (k=1~j-1) => f[i,j]=min{f[i,j-1]-|a[i]-j|,f[i-1,j-1]}+|a[i]-j| 2.给定一个带权值的M*N矩形方阵,去掉k个格子,要求剩下的任何一个格子都可以看到右边界和下边界,求去掉格子权值之和最少值 f[i,j,k]=min{f[i-1,j',k-j}+s[i,j] (j'=j+1~n) => f[i,j]=min{f[i,j+1,k+1]-a[i,j+1],f[i-1,j,k-j]+s[i,j]} |
|
|