目录
- 知识点
- 题目
- 1.邮票 Stamps
- 2.木棍加工
- 3.种树
- 4.钓鱼
- 5.[NOIP2015 普及组] 推销员
- 6.[NOIP2013 普及组] 车站分级
- 7.Work Scheduling G
- 8.[NOIP2015 提高组] 斗地主
- 9.扇区填数
- 10.[AHOI2018初中组]分组
- 11.三角形牧场
- 12.[NOI2014] 起床困难综合症
- 13.[NOIP1999 提高组] 旅行家的预算
- 14.[NOIP2012 提高组] 国王游戏
- 15.[国家集训队]特技飞行
- 16.[NOIP2010 提高组] 关押罪犯
- 17.[HAOI2008]糖果传递
- 18.[ZJOI2006]皇帝的烦恼
- 19.[USACO10JAN]Cow Telephones G
- 20.豪华游轮
- 21.上升序列
- 22.[HAOI2007]覆盖问题
- 23.合并神犇
知识点
- 1.不下降子序列最小个数等于最大上升子序列的长度
- 2.反悔贪心有两种思路,换效果最差的一个,开优先队列多次替换
- 3.可以开多个数组记录中间答案,可以实现复杂度的降低
- 4.贪心可以转化成模型(分纸牌)
- 5.dp和贪心加和
题目
1.邮票 Stamps
给一组 n 枚邮票的面值集合和一个上限 k —— 表示信封上能够贴 k 张邮票。请求出最大的正整数 m,满足 1 到 m的面值都可以用不超过 k 张邮票表示出来。
- 背包的体积表示:f[i],表示出i的面值最少用多少张邮票
2.木棍加工
- 先以第一关键字(长度)排序,然后求要求不下降子序列的最小个数,就是最长上升子序列的长度
3.种树
每个居民都想在门前种些树,并指定了三个号码 b,e,t。这三个数表示该居民想在地区 b 和 e 之间(包括 b 和 e)种至少 tt棵树。
- 可以用差分约束
- 贪心,要种树种得少,就要使一棵树给多个区间使用,这样,尽量在重叠区间种树即可,而重叠位置一定是区间尾部。处理问题时,先按所有区间的结束位置从小到大排序,若结束位置相同,则按开始位置从大到小排序。之后依次处理每个区间,先在第一个区间尾部种满足要求的树,对下一个区间,看差多少棵就在该区间尾部种多少。
- 开vis数组,标记每一个地方有没有种树,在每一个区间内从后往前种树
4.钓鱼
- 我们可以先确定可以走到的最远的鱼塘i,然后把时间减去从鱼塘1走到鱼塘i的时间,在剩下的时间里一直钓鱼,可以假设钓鱼人可以瞬间移动,在鱼塘1到鱼塘i之间采用上面的贪心方法,就可以求到最远走到鱼塘i的最优解。
- 我们设在池塘i花了k个单位时间钓鱼,从池塘i-1走到池塘i要花t[i-1]的时间。那么opt[i][j]就等于opt[i][j-t[i-1]-k](即到上一个池塘花j-池塘i-1到池塘i的时间-k的单位时间的最优解)加上在池塘i花k个单位时间钓到的鱼,那么就可以得到
o p t [ i ] [ j ] = m a x o p t [ i − 1 ] [ j − t [ i − 1 ] − k ] + k ∗ f [ i ] − d [ i ] − 2 ∗ d [ i ] − 3 ∗ d [ i ] − … − ( k − 1 ) ∗ d [ i ] opt[i][j]=max{ opt[i-1][j-t[i-1]-k]+k*f[i]-d[i]-2*d[i]-3*d[i]-…-(k-1)*d[i] } opt[i][j]=maxopt[i−1][j−t[i−1]−k]+k∗f[i]−d[i]−2∗d[i]−3∗d[i]−…−(k−1)∗d[i]
5.[NOIP2015 普及组] 推销员
- dp很好推(半区间dp)
- 贪心,舍去前i个中,价值最小的,换位后面距离更远的,只需舍去最小值来走更远,无需舍去更多数来走更远。
6.[NOIP2013 普及组] 车站分级
-topo排序,点少的时候,邻接表判断重边显然较快
7.Work Scheduling G
对于第 i 个工作,有一个截止时间 D i D_i Di,如果他可以完成这个工作,那么他可以获利 P i P_i Pi. 在给定的工作利润和截止时间下,约翰能够获得的利润最大为多少.
- 反悔贪心,优先队列,时间够,塞进去,时间不够,看能不能把最小的价值替换出来
8.[NOIP2015 提高组] 斗地主
- 大的搜索,还是if else.
9.扇区填数
-先推出结论,再利用结论搜索
10.[AHOI2018初中组]分组
- 二分答案+map
- 二分查找+贪心
- 二分答案+贪心
- map+贪心
- 转化成俄罗斯方块的消方块问题
- 把能力连续的放到目前可以放的且siz最小的组里(也可以不考虑吧siz)
11.三角形牧场
- 海伦公式 s q r t ( p ∗ ( p − a ) ∗ ( p − b ) ∗ ( p − c ) ) sqrt(p*(p-a)*(p-b)*(p-c)) sqrt(p∗(p−a)∗(p−b)∗(p−c)) p = ( a + b + c ) / 2 p=(a+b+c)/2 p=(a+b+c)/2
- n块都要用
- 海伦公式
- 状态 三边开不下 存两条边 前k个板子 两边长为i或j
- 到达型dp+枚举
12.[NOI2014] 起床困难综合症
- 位运算,0 的32位全是0,-1的32位全是1,利用这一特性就可以计算
13.[NOIP1999 提高组] 旅行家的预算
- 搜索
- 贪心:1.不管加多少油,只要能到达下一个费用比当前小的点,就加多少油,然后直接到下一个点
3。没有花费低的加油站情况下,如果能直接到终点,就直接到终点
2.如果到不了,就加满,到一个最小花费的加油站
14.[NOIP2012 提高组] 国王游戏
- 可以这样进行数学证明:
1.假设只有两个人,分别是L1 R1 L2 R2
2.算出来一排在前面和二排在前面获得的金币的最大值
3.令一排在前面的最大值更优一些,得到L1R1<L2R2
4.要更严谨一点可以设出来前面的乘积base
15.[国家集训队]特技飞行
- 把答案和执行的顺序连接起来,空掉中间的部分,随意填
16.[NOIP2010 提高组] 关押罪犯
- 二分答案+二分图判定
- 贪心+并查集
17.[HAOI2008]糖果传递
- 和负载平衡是一样的,分纸牌游戏,中间可以拆开,判断前缀和的中位数,
- 中间肯定有两个人之见没有交换,所以可以把一个看做队首,一个看做队尾,根据前缀和计算设总牌数为
s
u
m
(
即
s
u
m
=
∑
a
[
i
]
)
sum(即sum=\sum{a[i]})
sum(即sum=∑a[i]),则每个人最后会各自有
T
=
s
u
m
n
T=\frac{sum}{n}
T=nsum张牌,设
g
[
i
]
=
T
−
a
[
i
]
g[i]=T-a[i]
g[i]=T−a[i]则让前k个人牌数相同需要的交换牌数为
∑
i
=
1
i
≤
k
∣
s
[
i
]
∣
\sum\limits_{i=1}^{i\leq k}{|s[i]|}
i=1∑i≤k∣s[i]∣其中
s
[
i
]
=
∑
j
=
1
j
≤
i
g
[
i
]
s[i]=\sum\limits_{j=1}^{j\leq i}g[i]
s[i]=j=1∑j≤ig[i],可以这样理解,要让前k个人牌数相同,要依次让前
1
,
2
,
3
…
k
−
1
1,2,3…k-1
1,2,3…k−1个人牌数相同,多退少补,会与后边的人发生二者之差绝对值的牌数交换。所以移动总牌数
a
n
s
=
∑
∣
s
[
i
]
∣
ans=\sum{|s[i]|}
ans=∑∣s[i]∣
按开始的序列顺序,像普通均分纸牌一样处理出 s s s数组,那么假设枚举的位置为 k k k,则类比普通均分纸牌求法,新的 s [ i ] = s [ i ] − s [ k ] s[i]=s[i]-s[k] s[i]=s[i]−s[k](注意ss为前缀和),于是 a n s = ∑ ∣ s [ i ] − s [ k ] ∣ ans=\sum{|s[i]-s[k]|} ans=∑∣s[i]−s[k]∣,我们套用中学数学知识可知当 s [ k ] s[k] s[k]为 s s s中位数时, a n s ans ans最小。于是本题就解决了。
18.[ZJOI2006]皇帝的烦恼
- 容斥原理+贪心+dp+二分答案
- 这是个环形的,所以要考虑第一个和最后一个有没有冲突,所以开mi数组表示最少会有几个重复的,状态转移过程中,发现还和上一个的最大重复有关系,所以再开mx数组表示最多会有几个重复的,转移之后,判断二分的mid可不可行就可以
19.[USACO10JAN]Cow Telephones G
- 树形dp,计算经过每一个根节点的通话对数,把剩下的没有通话的牛的个数记录一下,传递到父节点
20.豪华游轮
- 贪心+背包
- 先向前走,走到头,然后看能不能拐最接近180的度数,拐之后,再继续走,用余弦公式计算离原点的距离就可以
21.上升序列
- dp模改,题目中要求的是下标字典序最小的,长度为x的上升子序列,倒序枚举,看上升子序列,再正向边判断,边输出
for(int i=n;i>=1;i--)
{
f[i]=1;
for(int j=i+1;j<=n;j++)
{
if(a[i]<a[j])
{
if(f[i]<f[j]+1)
{
f[i]=f[j]+1;
}
}
}
mx=max(mx,f[i]);
}
int t=tmp,last=-1;
for(int i=1;i<=n&&t>0;i++)
{
if(f[i]>=t&&a[i]>last)
{
printf("%d ",a[i]);
last=a[i];
t--;
}
}
printf("\n");
22.[HAOI2007]覆盖问题
- 贪心+二分答案+搜索
- 先二分枚举正方形边长,枚举每一次把当前这个正方形放在 ( m i n x , m i n y ) , ( m i n x , m a x y ) , ( m a x x , m i n y ) , ( m a x x , m a x y ) (minx,miny),(minx,maxy) ,(maxx,miny),(maxx,maxy) (minx,miny),(minx,maxy),(maxx,miny),(maxx,maxy)中的哪一个角落,一定要覆盖到一个角落,否则就会导致后面放的不优,最后看能不能完全被三个正方形覆盖
23.合并神犇
- 贪心+dp
- 由题目可以知道,合并越少越好,所以,最后一次合并的越少,总的结果就越优化,这个题和划分是一样的道理
for(int i=1;i<=n;i++)
{
int j;
for(j=i-1;j>=0;j--)
{
if(sum[i]-sum[j]>=g[j]) break;//合并的最少
}
f[i]=f[j]+i-j-1;
g[i]=sum[i]-sum[j];
}
printf("%lld",f[n]);