ACM第三次辅导之贪心枚举模拟
模拟、枚举、贪心

枚举
使用枚举算法的解题步骤
• • • • 1. 找到问题的定义集。 2. 分析元素的认证方法。 3. 分析如何从解集获取试题所需要的答案。 转1,分析其他的定义集 1
枚举算法的程序
• 枚举所有属于定义集中的元素;(定义集 生成) • 对每个元素,判断其是否在解集中; • 对解集中的元素进行处理,计算问题的答 案。
分析
• 分析目标
– Σ|xi/y-ki/m| ->Σ|xi/y*m-ki|
• 利用绝对优势缩小范围
– [xi/y*m]<=ki<=[xi/y*m]+1 – 令初始全为[xi/y*m]
• 顺应题意
– 每次增加一个ki使差答案最小。 – 即增加{xi/y*m}最大且没增加过的。
• {x}表示x的小数部分。
枚举算法框架
• • • • • • • • • • • • • function test(e): boolean; { 认证函数} begin test := 是否满足条件 end; procedure proc(e); { 处理函数} begin end; begin for I in 定义集do if test(i) then { 解集} proc(i); end.
使用枚举算法的解题步骤
使用枚举算法的解题步骤 1. 找到问题的定义集。 2. 分析元素的认证方法。 3. 分析如何从解集获取试题所需要的答 案。 • 转1,分析其他的定义集 • • • •
例1 和质数问题
• • • • 问有多少组a, b满足: a为1至100的整数 b为1至100的整数 a+b为质数 a+b
模拟将题目看清楚建议在试卷上把关键点都画下来简化题面把每个关键点牢记在心不要出现遗漏的状况测试数据要出全面主要是有特点的小数据或者几个特点结合起来的中间数据
信息学竞赛中的模拟与贪心算法模板

信息学竞赛中的模拟与贪心算法模板在信息学竞赛中,模拟与贪心算法是常用的解题思路之一。
它们能够在面对各种问题时提供简洁高效的解决方案。
本文将介绍信息学竞赛中常用的模拟与贪心算法模板,帮助选手更好地应对竞赛题目。
一、模拟算法模板模拟算法通过模拟问题的过程,逐步逼近问题的答案。
常见的模拟算法包括枚举、模拟、暴力搜索等。
下面将以几个经典的问题为例,介绍模拟算法的模板。
1. 枚举枚举是一种穷举所有可能的方法。
可以用来解决一些指定范围内的问题,如排列组合、数字结构等。
常见的枚举方法有递归枚举、位运算枚举等。
2. 模拟模拟是一种按照题目要求,逐步模拟问题的过程。
通常需要设计好数据结构和算法,以便进行模拟计算。
在模拟算法中,需注意边界条件的处理,以确保模拟的正确性。
3. 暴力搜索暴力搜索是一种穷举所有可能情况的方法,通过遍历搜索空间,找到问题的所有可能解。
暴力搜索常用于解决规模较小的问题,时间复杂度较高。
二、贪心算法模板贪心算法是一种在每一步都选择当前状态下最优解的算法。
它通过局部最优解的选择,逐步构建出全局最优解。
贪心算法的关键在于确定每一步的最优选择策略。
常见的贪心算法模板如下:1. 确定问题的贪心策略贪心算法的关键在于确定每一步的最优选择。
根据问题的性质,分析问题的特点,选择适当的贪心策略。
2. 构建贪心算法的循环根据确定的贪心策略,使用循环来逐步构建解决方案。
在每一步选择最优解后,更新相关状态,并进入下一步。
3. 判断是否达到全局最优解判断当前选择是否达到全局最优解。
如果是,则终止算法并输出结果;否则继续选择下一步的最优解。
贪心算法的设计思路需要充分理解问题本身,熟悉问题的特点,并根据实际情况灵活运用。
总结:信息学竞赛中,模拟与贪心算法是常用的解题思路。
本文介绍了模拟算法和贪心算法的模板。
在实际应用时,选手们需要根据题目要求和问题的特点,灵活运用这些模板,找到最适合的解决方案。
通过不断的练习和实践,提升自己的解题能力,在竞赛中取得优异的成绩。
ACM模拟题目(第三次)

注:两个题目可选做一个,也可两个都做。
难度不一定按顺序排列。
题目1:核电站问题题目描述一个核电站有N个放核物质的坑,坑排列在一条直线上。
如果连续M个坑中放入核物质,则会发生爆炸,于是,在某些坑中可能不放核物质。
任务:对于给定的N和M,求不发生爆炸的放置核物质的方案总数输入格式输入文件只一行,两个正整数N,M( 1<N<50,2≤M≤5)输出格式输出文件只有一个正整数S,表示方案总数。
样例输入题目2:小t的游戏Problem Description小t有点神经质,喜欢发明一些稀奇古怪的游戏,比如说左手和右手打架就是他发明的。
这个周末,小t又发明了一个有趣的硬币游戏:小t手里有6枚硬币,他把硬币分成了两堆,一左一右并排堆放,一堆2个,一堆4个。
然后他开始从这两个堆中各取出1个硬币,再组成一个新的堆放在最右边。
用(2,4)表示初始两堆,于是作下抽象,第一次操作后(2,4)变成了(1,3,2)。
小t继续操作,他从这三堆中继续各取出1个硬币,组成新堆放到最右边。
于是(1,3,2)变成了(0,2,1,3),去掉空堆,变成(2,1,3)。
小t继续进行以上操作并去除空堆,(2,1,3)变成了(1,2,3)。
这时,小t发现如果继续做同样的动作,分堆的硬币不会再有变化了,一直都是(1,2,3)状态,也就是陷入了循环节为1的循环。
小t突发奇想,他想知道:如果知道硬币的分堆数,和每堆硬币的个数,执行“每次从已有的每一堆硬币中取出1个硬币,凑成新堆”的操作,用(a,b,c,d,….)表示分堆状态(其中a,b,c,d…每个字母都是正整数),分堆状态是否会陷入循环,如果陷入循环,循环节又是多少呢。
Input输入有很多组case,每组case第一行一个正整数n (n<65536),表示硬币分为多少堆第二行有n个整数,每个数k<65536,表示每堆有多少个硬币,每个数后面都有一个空格。
Output如果分堆状态陷入循环,输出分两行,第一行输出yes,第二行输出一个整数表示循环节长度。
北大ACM题型

3.C[i,j]=w[i,j]+opt{C[i,k-1]+C[k,j]}.(最优二分检索树问题)
六.数学
(1)组合数学:
1.加法原理和乘法原理.
2.排列组合.
3.递推关系. (POJ3252,poj1850,poj1019,poj1942)
(2)数论.
1.素数与整除问题
(2)扫描线算法(例如求矩形的面积和周长并,常和线段树或堆一起使用). (poj1765,poj1177,poj1151,poj3277,poj2280,poj3004)
(3)多边形的内核(半平面交)(poj3130,poj3335)
(4)几何工具的综合应用.(poj1819,poj1066,poj2043,poj3227,poj2165,poj3429)
(2)记录状态的动态规划. (POJ3254,poj2411,poj1185)
(3)树型动态规划(poj2057,poj1947,poj2486,poj3140)
六.数学
(1)组合数学:
1.容斥原理.
2.抽屉原理.
3.置换群与Polya定理(poj1286,poj2409,poj3270,poj1026).
五.动态规划
(1)需要用数据结构优化的动态规划. (poj2754,poj3378,poj3017)
(2)四边形不等式理论.
(3)较难的状态DP(poj3133)
六.数学
(1)组合数学.
1.MoBius反演(poj2888,poj2154)
2.偏序关系理论.
(2)博奕论.
----------------------------------------------------------------------------------------------- -----------------------------------补充 Dp状态设计与方程总结
ACM之贪心&动态规划

仅仅在完全背包转移方程上改了一个界 多重背包可以转换为0/1背包,即把每种物品拆成一个一 个的物品。时间复杂度O(V*Σlimit[i])。 更高明的拆法:二进制。拆成1,2,4,8…limit[i]-2^k,k为最 大的使得2^k<limit[i]的整数。详情参看背包九讲之第三讲 推荐多重背包练习
O(n^3)
稍加优化 可以提前开一个辅助数组sum[],sum[i]为 前i项和,然后只需遍历起始点i和终止点j, 答案为sum[j]-sum[i-1]的最大值 时间复杂度
O(n)预处理+O(n^2)
分治法求解 将所求拆分成几个部分,各个击破 将a[1…n]分成两部分a[1…n/2]和a[n/2+1…n] 则a[1…n]最大子段和可以分成如下几个子问题
为什么? 因为0/1背包中,每种物品最多只能取一次,如果 递增,则会出现将某件物品重复加到背包里的错 误,所以要递减,而完全背包刚好要重复利用某 些物品,可以直接改一个递推的方向就可以了。
多重背包
特点:每种背包限制了个数 状态转移方程
f[j]=max{f[j],f[j-k*W[i]]+k*P[i]|0<=k<=limit[i]}
dp[j]=max{dp[j-1]+a[j],a[j]} 等效为 若dp[j-1]>0,dp[j]=a[j] 否则dp[j]=dp[j-1]+a[j]
最大子段和推广
最大子矩阵和 最大子长方体和
最大m子段和
作业
aoj363取数字问题 题目叙述错误,更正:
“每一步只能向下或者向下”改成“每一步只
f[j]=max{f[j],f[j-k*W[i]]+k*P[i]|0<=k*W[i]<=v} 这是最优的吗?……No!
ACM题目分类

(1)串 (poj1035,poj3080,poj1936)
(2)排序(快排、归并排(与逆序数有关)、堆排) (poj2388,poj2299)
(3)简单并查集的应用.
(4)哈希表和二分查找等高效查找法(数的Hash,串的Hash)
(3)点集最小圆覆盖.
(4)对踵点(poj2079)
八.综合题.
(poj3109,poj1478,poj1462,poj2729,poj2048,poj3336,poj3315,poj2148,poj1263)
同时由于个人练习的时候可能有些偏向性,可能上面的总结不是很全,还请大家提出和指正,而且由于ACM的题目中专门针对某个算法的题目可能比较少出现,所以上面的分类中的题有可能有多种解法或者是一些算法的综合,这都不会影响大家做题,希望练习的同学能够认真,扎实地训练,做到真正的理解算法,掌握算法. 同时在论坛上还有许多前辈的分类,总结,大家也可以按自己的情况采用.注意FTP上有很多的资料,希望大家好好地利用.
目的). (poj2823)
(4)左偏树(可合并堆).
(5)后缀树(非常有用的数据结构,也是赛区考题的热点).
(poj3415,poj3294)
四.搜索
(1)较麻烦的搜索题目训练(poj1069,poj3322,poj1475,poj1924,poj2049,poj3426)
(5)杂题.
(poj1870,poj3296,poj3286,poj1095)
七.计算几何学.
(1)坐标离散化.
(2)扫描线算法(例如求矩形的面积和周长并,常和线段树或堆一起使用).
(poj1765,poj1177,poj1151,poj3277,poj2280,poj3004)
信息学竞赛(noip) 枚举、模拟、贪心共69页文档

8、法律就是秩序,有好的法律才有好的秩序。——亚里士多德 9、上帝把法律和公平凑合在一起,可是人类却把它拆开。——查·科尔顿 10、一切法律都是无用的,因为好人用不着它们,而坏人又不会因为它们而变得规矩起来。——德谟耶克斯
44、卓越的人一大优点是:在不利与艰 难的遭遇里百折不饶。——贝多芬
45、自己的饭量自己知道。——苏联
41、学问是异常珍贵的东西,从任何源泉吸 收都不可耻。——阿卜·日·法拉兹
42、只有在人群中间,才能认识自 己。——德国
43、重复别人所说的话,只需要教育; 而要挑战别人所说的话,则需要头脑。—— 玛丽·佩蒂博恩·普尔
ACM训练贪心专题

先总结一下:
这次的练习虽然是贪心的主题,但是我在选题的时候还是故意的选了两道,一道水题,一道稍微难一点。
来让大家分辨出是不是贪心。
Problem A
题意:输出能观看的最多的节目数。
按照时间排序,根据时间的起点和终点进行贪心即可。
Problem B
题意:看似背包问题,实质为贪心。
贪心专题一换豆子的变形。
按性价比排序然后,把体积作为限制条件,一次贪心即可。
Problem C
题意:这个题目的几乎没有童鞋AC了,很是诧异。
题目没有看懂?d:在第几天开始,s:开始的时间,e:结束时间。
显然,要先根据d排序,然后按照s或者e排序.接着根据临街判定条件一次贪心即可。
貌似也是贪心练习二中的“今年暑假不AC”的变形。
Problem D 题意:非贪心题目。
看懂题目暴力枚举即可。
Problem E
题意:同A题和C题。
不过不是求最多的战争数目,而是求了一种求法。
Problem F
题意:非贪心题目。
数学题。
掺杂字符串操作。
详细看代码注释。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
贪心
有一个容量为M的背包,同时还有n个物品,第i个物品的重 量为v[i],价值为w[i],每个物体可以拆分成无限份。在放入的物 品的总重量不超过背包容量的前提下,尽可能让装入背包的物品 总价值最大。
(2)部分背包问 题:
贪心
第一种贪心策略:每次选取价值最大的物品(错误) 反例:
物品 A B C W = 30 重量 30 20 10 价值 30 20 20
枚举
一种盲目的搜索方法,将所有可能的情况都考 虑到,并逐一判断。
枚举
枚举是一种非常暴力的算法,是一种非常盲目的求解问题 的方法。它通过将所有可能的解逐一列出,并加以判断,最终求 解出最符合题意的答案。使用枚举前一定要判断是否会超时,并事件的 所有可能情况,因而得出一般结论,那么这结论是可靠的,这种 归纳方法叫做枚举法。特点:将问题的所有可能的答案一一列举, 然后根据条件判断此答案是否合适,合适就保留,不合适就丢弃。
目录
1 2 3
贪心
枚举
模拟
4
时间/空间复杂度&习题讲解
贪心
一种改进了的分级处理方法,通过选取局部最优, 希望得到整体最优的结果。
贪心算法思路
顾名思义,贪心算法总是在当前情况下做出最好的选择, 而不是从整体考虑。贪心算法始终相信:整个问题的最优解一定 是由贪心策略中存在的子问题中得来的。 运用贪心算法做出的选择可以说是局部最优,这与我们之 后将要学习的“动态规划”的思想很不相同。贪心算法和动态规 划算法都是一种递推算法,都运用局部最优解来推导全局最优解。 不同的是,贪心算法推导某一步的最优解时只运用了上一步的最 优解,动态规划算法则是运用了之前的所有最优解。这是因为贪 心算法每一步做出的策略都无法改变,当推导出某一步的最优解 时,之前的所有最优解则不做保留。
时间/空间复杂 度 例如,若有T(n) = n + n(n+3)/2 + n(n+1)/2,则有
所以时间复杂度为O(n^2)。
常见时间复杂度有常数阶O(1)、线性阶O(n)、平方阶O(n^2)、 立方阶O(n^3)。另外,算法的时间复杂度有时还可能呈现为对数 阶O(log2(n))或是指数阶O(2^n)。
枚举
只需要在给定的范围内,依次枚举a、b、c、d的值,同时 a<b<c<d。所以只需要写出4个for循环枚举即可。n最大100,所以 O(n^4)的解法不会超时。但是假如n最大1000,这种暴力枚举的方 法就很可能超时。
枚举
枚举的特点
得到的结果肯定是 正确的
通常会涉及到求极 值(如最大,最小, 最重等)
枚举可以说是几层for循环,再加以少数判断,我们现在做 的很多题目都是枚举。
枚举步骤
1
选取要枚举的对 象
2
开始枚举,逐个 检查
3
选取判断标准, 一定要做到全面, 确保无遗漏,尽 早发现不是解的 情况。
枚举
Perfect Cubes (POJ 1543)
若a^3 = b^3 + c^3 + d^3则称为完美立方,输入n,按照a、b、 c、d从小到大的顺序输出所有的满足完美立方条件的a、b、c、d, 同时a < n。 样例输入:
利用贪心算法求解最优问题的步骤
选定合适的贪心选择的标准
1
贪心
4
选定合适的贪心选择的标准
2
证明在此标准下该问题具 有贪心选择性质
3
证明该问题具有最优子结 构性质
加油!
说人话
贪心
贪心算法并不是什么高深的算法,这种局部最优的思想在 生活中非常常见。 比如,A花了49块钱去吃自助餐,可以选择的有牛排、扇贝、 烤肉,也有炒饭、爆米花。如果A希望在吃饱之前尽可能把自己花 出去的49块钱吃回来,那么他会选择吃什么?当然选择吃那些体 积小、价格贵的食物。这就运用到了贪心的思维。 下面看几个经典的问题。
贪心
第三种贪心策略:每次选取单位重量价值最大的物品(正确)
物品 A B C
W = 30 重量 30 20 10
价值 30 20 20
物品 A B C
W = 30 重量 30 20 10
价值 50 20 20
对于前两组样例,第三种贪心策略都能得到正确答案。不 仅仅是对于以上两组,对于本问题的任何情况,这种策略都能得 到正确的解。
贪心
情况2:区间1与区间2相交 区间1 区间2
①
②
图中黄色部分①其实是无效部分,因为它不与任何区间相交! 所以区间1可以看作是②,接下来就变成了情况1,所以选择区间 1一定最优。
贪心
情况3:区间1与区间2不相交 区间1 区间2
区间1与区间2不相交,选择区间1毫无疑问最优。
贪心
区间1 区间2 区间3 区间4 区间5 区间6
贪心
(4)01背包问题:
一个容量为40的背包和3件物品,每件不能拆分,可以选择 放还是不放,在不超过背包容量的前提下使放入背包的物品价值 最大。
物品 A B C W = 40 重量 30 20 20 价值 50 20 20
这种时候情况下,无论第三种贪心策略是错误的,所以这 道题不能用贪心求解!
贪心
① ②
可能做了很多的无 用功,浪费了宝贵 的时间,效率低下
③
模拟
将事物的某些信息抽象化为程序中的数据,模 拟事物的某个过程。
模拟
大家之前做到的“今天是×年×月×号星期× ,求1000天 以后是几月几号”的题目就属于模拟。 模拟对于编程初学者来说是一种非常常见的题目,而且目 前大家遇到的模拟题基本上都比较简单。模拟并不需要会什么高 深的算法,这类题目比较考验的是细心和耐心。也没有什么技巧, 需要多多的练习。
补充:
时间/空间复杂 度
①.当执行语句的次数是一个常数,即语句频度T(n)为一个常数时, 无论T(n)多大,时间复杂度都是常数阶O(1)。
②.因为二分的思想非常常见,以后我们可能会经常见到O(log(n)) 这样的写法,这种写法代表的都是O(log2(n))。
③.当语句执行的次数不仅仅由n,而是由多个未知数决定时,除n 外的未知数又是选择忽略,有时怎不能忽略,视情况而定。比如, 矩阵相乘时矩阵阶数可以忽略掉,而在进行字符串匹配时,无论 使用BF算法(O(n * m))还是KMP算法(O(n + m)) ,模式串长度 m不可以忽略。这一点不太懂也没有关系,做到特定的题的时候 自然就懂了。
语句频度T(n)也随之变化。在一般情况下,当n不断增大时,我们 希望知道T(n)的变化呈现规律。为此,引入时间复杂度的概念。 设T(n)的一个辅助函数为g(n),若有
其中,A为一个常数,则称g(n)是T(n)的同数量级函数。把T(n)表示 成同数量级函数形式,即T(n)=O(g(n))称为算法的时间复杂度。时 间复杂度描述了n无穷大是算法语句频度的数量级。
贪心
对于这个问题,我们的贪心策略是:首先选择第一个区间, 然后寻找最先该区间的右边界之后第一个出现的区间,再以这个 区间的右边界为起点,寻找第一个出现的区间,以此类推。 但是为什么必须选择第一个呢?为什么不能从第二个区间 开始呢?
贪心
下面来讨论按照右边界排序之后的第1个区间和第2个区间 情况1:区间1包含于区间2 区间1 区间2 根据刚才的结论,选择区间1必定比选择区间2更优
时间/空间复杂 度 例:求下面一段代码的时间复杂度
时间/空间复杂 度
m是语句执行次数,即T(n)。这段代码的时间复杂度为O(√n)。
时间/空间复杂 度
空间复杂度的计算方法与时间复杂度极其相似,本节课不讲。
贪心算法思路
在贪心算法中,以自顶向下的方式使用最优子结构,也就 是说,贪心算法会先做出选择,在当时看起来是最优的选择,然 后再求解一个结果子问题,而不是先求解子问题的最优解,然后 再做出选择。 正是因为贪心算法是由上一步的最优解推导下一步的最优 解,而上一部之前的最优解则不作保留 ,它的“局部最优”只是 一种目光短浅的“最优”,贪心算法有时会解出错误的答案。可 能这也是这种算法的名字不太好听的一个原因。
准备利用贪心算法解某个问题的时候,确定该问题可以用 贪心的思想解决,最关键的是找到合适的贪心策略,这也是最难 的一点。 贪心算法不像我们之后要学习的快速幂、并查集一样有固 定的模版或者框架。贪心算法不是对所有问题都能得到整体最优 解,但对范围相当广泛的许多问题都能产生整体最优解或整体最 优解的近似解。 典型例子:哈夫曼编码,单源最短路径(Dijkstra算法), 最小生成树(Prim和Kruskal算法)
时间/空间复杂度&习题讲解
ACM选手必备技能——估算时间/空间复杂度 这次做题的同学比上一次少了好多,是英文 题的缘故吗?
时间/空间复杂度
时间复杂度
时间复杂度是指执行算 法所需要的计算工作量。
空间复杂度
空间复杂度是指在算法 执行过程中需要的辅助 空间数量。
时间/空间复杂 度 在语句频度T(n)中,n称为问题的规模,当n不断变化时,
24
样例输出:
Cube = 6, Triple = (3,4,5) Cube = 12, Triple = (6,8,10) Cube = 18, Triple = (2,12,16) Cube = 18, Triple = (9,12,15) Cube = 19, Triple = (3,10,18) Cube = 20, Triple = (7,14,17) Cube = 24, Triple = (12,16
给出n个物体,第i个物体重量为w[i] 。选择尽量多的物体, 使得总重量不超过C。
贪心
贪心
最简单的贪心题。 由于只关心物体的数量,所以装重的没有装轻的划算。所 以只需把物体按重量从小到大排序,一次选择每个物体,知道装 不下位置。这是一种典型的贪心算法,它只顾眼前,却能得到最 优解。