分数背包(部分背包):有一个容量为 V 的背包和若干物品,物品有重
量和价值。假设物品可以被无限细分,且细分后价值重量比不变。求可
以装下的最大价值。假设物品可以被无限细分,且细分后价值重量比不变。
贪心的做法:优先装性价比高的物品,直到这种物品用完或背包
装满
01 背包:有一个容量为 V 的背包和若干物品,物品有重量和价值。物
品不能被分割。求可以装下的最大价值。贪心的做法:优先装性价比高的物品?
反例:背包容量为 4,三个物品的价值/重量分别为 3/30,2/19,2/19
可以使用动态规划来解决
https://www.luogu.org/problemnew/show/P3817
给出长度为 n 的整数序列 a1...an 和整数 x,每次操作可以使任意数字减
少 1,求最少操作多少次可以使所有相邻两个数字的和小于等于 x从左往右按对考虑
对于 a1 和 a2,如果 a1 + a2 > x,那么必须操作 a1 + a2 - x 次
减少 a2 相比减少 a1 更优,因为可能省下之后的操作
于是除非a1 本身已经大于 x,则只要减少 a2
依次向右重复操作,累加得到答案
if (a[1]>x){
ans+=a[1]-x;
a[1]=x;
}
for (i=2;i<=n;i++)
if (a[i-1]+a[i]>x){
ans+=a[i]+a[i-1]-x;
a[i]=x-a[i-1];
}
https://www.luogu.org/problemnew/show/P1094
给出 n 个数字,需要分成若干组,每一组只能有 1 或 2 个数,且总和
不能超过 w,求最小组数
https://www.luogu.org/problemnew/show/P2587
两队各有 n 个选手一对一进比赛,胜者得 2 分,平局各得 1 分,负
者不得分。给出每个选手的实力值,求安排一种顺序使得自己队得分
最高田忌赛马
如果最强的能战胜对方最强的,那么一定会安排这场比赛
如果最菜的能战胜对方最菜的,那么也一定会安排这场比赛
否则就把最菜的送给对方最强的(注意判断平局)
https://www.luogu.org/problemnew/show/P5019
长度为 n 的整数序列 a1...n,每次操作可以选择连续且不含零的一段减
少 1,求最少操作多少次可以全部变成0从左往右考虑:对于 a1,至少要以 1 为左端点操作 a1 次
为了使这些操作的收益最大,需要尽量将它们的右端点向右移
如果 a1 ≤ a2,就向右延续,再额外加上 a2 - a1 次操作
如果 a1 > a2,有一些操作会被挡住,只有 a2 次可以继续往右延伸
对原数组差分,然后对大于零的元素进行求和得到答案
https://www.luogu.org/problemnew/show/P1223
有 n 个人排队接水,每个人花的时间不一样。需要确定一个接水的顺
序,使得等待时间的平均值最小
要最小化等待时间的平均值,实际上就是最小化总的等待时间
总的等待时间 =∑ 每个一花的时间 × 排在他后面的人数
问题等价于给每个人分配一个 0 ~ n - 1的权重,最小化带权和
根据直觉,应该让耗时较短的人拥有较小的权重(先打水),反之
亦然
证明:对于任意两个耗时不同的人,考虑交换它们的权重
实际上就是排序不等式
https://www.luogu.org/problemnew/show/P1090
Huffman 编码
考虑这样一种压缩算法:将每个字符用长短不一的二进制数来表示,
满足没有任何一个是另一个的前缀。
现在给出字符的出现次数,求能让压缩后总长度最短的编码方式我们发现,编码可以构成一棵 trie 树
压缩后的总长度 = 每个字符出现次数 * 它的码长(树上到根的距
离)
根据直觉,应该让出现次数高的字符码长更短,反之亦然
引理:存在一种最优方案,使得出现次数最少的两个字符深度相
同,且在树上为兄弟
那么将这两个字符合并,看成一个字符,但每当它们出现时需要
额外的一个码长来分辨
递归地构建出 Huffman 树,得到最优编码
https://www.luogu.org/problemnew/show/P1803
数轴上有 n 个线段,给出左右端点,求可以选出的最多的不相交线段
(端点可以重合)。考虑把选出的线段从左往右排成一排
对于最左边的线段,我们希望它的右端点尽可能靠左,来留出更
多空间
得到贪心算法:按照右端点排序,从左到右,能选则选
正确性显然
付钱问题
有 1 元,2 元,5 元三种面额的钱,需要支付 n 元,求使用的最少钱币
数.
按照 5,4,1 元依次付不太行
反例:如果支付 8 元,5+1+1+1 不如 4+4
如果 n 较小,可以使用动态规划
如果 n 很大,可以先贪心使用 5 元,直到可能出现反例开始动态规划
https://www.luogu.org/problemnew/show/P2060
给出棋盘上两个点的坐标,求马(走马字)从一点跳到另一点需要的最
少步数如果棋盘较小可以 bfs,但是本题中坐标范围很大
大范围进贪心,小范围进行 bfs
小范围也可以打表
高精度
通常,整数数组来存储数字(十进制)的每一位
如果需要小数部分,可以再用一个数组来存
为了方便计算,一般按照十进制从低位到高位的顺序来存
a[0] 存个位,a[1] 存一位,a[2] 存百位
为了效率,可以进行压位(一个位置存多个十进制位)高精度
加
乘
卷积形式
ck=ai*bj (i+j=k)
https://www.luogu.org/problemnew/show/P1645
https://www.luogu.org/problemnew/show/P2142