【考试】list2

知识点

  • 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[i1][jt[i1]k]+kf[i]d[i]2d[i]3d[i](k1)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(pa)(pb)(pc)) 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]}) sumsum=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]=Ta[i]则让前k个人牌数相同需要的交换牌数为 ∑ i = 1 i ≤ k ∣ s [ i ] ∣ \sum\limits_{i=1}^{i\leq k}{|s[i]|} i=1iks[i]其中 s [ i ] = ∑ j = 1 j ≤ i g [ i ] s[i]=\sum\limits_{j=1}^{j\leq i}g[i] s[i]=j=1jig[i],可以这样理解,要让前k个人牌数相同,要依次让前 1 , 2 , 3 … k − 1 1,2,3…k-1 1,2,3k1个人牌数相同,多退少补,会与后边的人发生二者之差绝对值的牌数交换。所以移动总牌数 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]);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值