2025/1/16 NOIP模拟赛

T1

这题是一个很好的题。
首先在赛时的思路是一个贪心,将整个数列从小到大进行排序,倒着扫整个序列,先把大的满足了再回来满足小的,以此类推。
code
这个思路是错误的,不难构造出一组数据来卡掉。
对于10 5 5 5 5 5 5 1 1 1 1这组数据,正确答案是\(5\),按上面贪心答案是\(2\)
根本原因在于贪心是把这一堆\(5\)放在了一起,事实上,我们并不需要把他们放在一起,完全可以构造出来一个另外的解法。
数据比较仁慈,我们拿到了\(81pts\)的好成绩。

满分解法\(1\):

先对整个序列进行从小到大排序。
考虑\(dp\)求解,设定\(dp\)状态为:\(dp_i\)表示到了第\(i\)个位置可以分的最多的桌子个数,易得转移方程:

\[f_i = \max_{i=0}^{i-a[i]}(f_j)+1(i-a_i >= 0) \]

不难发现这个正常的做法会是\(O(n^2)\)的,没有办法通过这个题目,考虑动态维护一个前缀最大值把求\(\max_{i=0}^{i-a[i]}(f_j)\)优化到\(O(1)\)
前缀最大值的思想就是计算出来当前这个后,更新对于当前位置的最大值,对于更新当前位置的最大值,要访问前一个的前缀最大值,具体实现如下:

for(int i = 1;i <= n;i++)
{
	if(i-a[i] >= 0)
	{
		dp[i] = sum[i-a[i]]+1;
	}
	sum[i] = max(dp[i],sum[i-1]);
}

时间复杂度为\(O(nlogn)\),复杂度瓶颈在于排序,如果采用计数排序的话,完全可以做到\(O(n)\)
code

满分做法\(2\):

贪心其实没有问题,不过需要更新一下做法。
先从大到小对于序列进行排序,还是先从前到后找到第一堆当作第一桌,然后反过来,正常从大到小进行贪心,贪剩下的就塞到第一堆,举个例子,例如有\(6\)\(5\)剩下一个就给她撇到第一个预处理的堆。
没有写,时间不是很够。

T2

贪心+模拟,观察复杂度,直接暴力枚举被修改的数,即是\(0-9\),然后再暴力算增量,判断一下字典序就可以了,基本就是模拟。
code

T3

好题。

\(40pts:\)

暴力计算出最长的区间左右端点,直接枚举\(T\)算贡献。

\(100pts:\)

做法\(1\):

观察一下对于\(a_i和b_i\)的数据范围,答案只跟序列左右端点和长度的相对大小有关,离散化就可以有效缩小需要枚举的范围。
对于每一个位置,我们可以采用树状数组将所有离散过后的数分别扔进去,维护一下每个位置数在数组中出现的个数,然后对于每一个\(T\),我们查询出来所有\(\le T\)的区间左端点个数\(a\)还有所有\(< T\)的区间右端点个数\(b\),那么对答案贡献为\(Z\)的区间,就是\(b\)的个数;对于答案贡献为\(Y\)的,就是区间左端点大于\(T\),但是区间右端点小于\(T\)的区间个数,就是\(a-b\)个;对于答案贡献为\(X\)的,显然就是\(n-a\)个,代码较为好写,写好离散化就可以了。
code

做法\(2\)

我们发现所有的查询都是在修改之后的,所以,你傻逼把,为什么要线段树和树状数组!(理塘丁真音)
yzh给出了更为nb的做法,忽然忆起昨日神秘T3,也是针对类区间求和,采用思想为差分,那么同理,在这里,我们也在需要修改的区间头尾打上差分标记,暴力\(O(n)\)求出区间和,然后继续计算就可以了!
code (来自yzh)

T4

神必状压\(dp\),拼尽全力,无法战胜嘛!
设定\(dp\)状态为:\(dp_{i,sta}\)表示当前已经扫到了第几串葡萄,这\(i\)串葡萄中后\(k\)串的选择状态为\(sta\),每一位状态上的\(0/1\)表示\(选/不选\)
考虑转移,注意到一个问题,二进制下每一位是用下标为\(0\)开始计算的,我们是倒着枚举,也就是枚举出\(i\)这一位的状态后,往前枚举能够转移到的状态,发现有两种情况,先将状态右移动一位,消除掉整个状态的最后一位,然后考虑从右往左数的第\(k\)为的状态,可以为\(0\)或者是\(1\),是\(1\)的话你就用右移后的数 或 上 \(1 << (k-1)\),因为上面提过了,二进制下是以\(0\)为下标起始的,所以是\((k-1)\),说一下为什么这么考虑,对于以下状态,可以被前面的转移过来:

那就显然了,对于\(dp\)初始值,你需要把\(dp_{0,k}\)的所有状态\(k\)都初始化成\(0\),剩下的是INT_MIN,在预处理出来\(dp_{0,k}\)的时候,计算出来没种状态下连续\(k\)个中\(1\)的个数,在转移的过程中,判断状态是否合法即可。
注意,tm的\(2^k\)在c++中是pow(2,k),不是2^k!!!!!!!
code
都写完了,回家咯。

posted @   Lunar_Whisper  阅读(2)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示