首页 > 其他分享 >CF div2 994 (A~E)

CF div2 994 (A~E)

时间:2025-01-09 12:32:36浏览次数:1  
标签:994 code ... CF 转移 确定 区间 移动 div2

VP赛时三题,自我感觉发挥不错,唯一不满意的地方在于D题完全没有思路。

A

答案最多为2,因为最坏情况即为先将整个区间合并为一个数,若这个数不是0,则再将这个数变为0。

所以3种情况分类讨论即可:

  1. 全是0,则不需要操作 -> \(0\)
  2. 只有一段非\(0\)连续区间 -> \(1\)
  3. 不止\(1\)个非\(0\)连续区间 -> \(2\)

code

B

首先,若只出现了一种字符,则一定可行,因为若只出现\(p\),则可令序列为\([1,2,...,n]\);若只出现\(s\)则可令序列为\([n,n-1,...,1]\)。

否则,两种字符一定都有。考虑任意一对\(p,s\):
设形成的前缀\((p)\)为\(1到k1\)的排列,后缀\((s)\)为\(1到k2\)的排列
易得前缀和后缀必然相互包含
所以检查是否有一对不相互包含的前后缀即可,实现不再赘述。

code

C

构造题

此题赛时的做法分讨得比较麻烦,但好在保证了正确性,还是官方题解的做法比较简洁。但感觉此题复盘的意义不大,故不再赘述。

code

D

\(dp\)

若没有对每一行循环左移操作,则就是一个普通的走迷宫\(dp\)。

由于每一行最多只会移动\(m - 1\)次,而\(n,m <= 200\),所以可以猜测是一个状态表示为\([行数][列数][对应行的移动次数]\)的\(dp\)。

状态表示:
\(g[i][j][k] :\) 从\((1,1)\)走到\((i,j)\),且第\(i\)行循环移动了\(k\)次,最小花费。
\(f[i][j] :\) 从\((1,1)\)走到\((i,j)\),最小花费。

考虑状态转移(此题重点):
由于每次只会向右或向下移动一格,所以\((i,j)\)的状态只会从\((i-1,j)\)和\((i,j-1)\)转移过来。

但由于引入了可对行循环左移的操作,使得这两种转移的方式并不一样:

1.\((i,j-1)\) -> \((i,j)\) : 由于题目明确要求必须在开始移动之前才能做循环左移操作,故对于行内的转移来说,必须要从当前行移动次数相同的状态转移过来。即:

g[i][j][k] <- g[i][j-1][k] + a[i][j`]

其中\(a[i][j`]\)表示第\(i\)行向左移动了\(k\)次后\((i,j)\)位置的数字

2.\((i-1,j)\) -> \((i,j)\) : 由于只能对行操作,因此行与行之间的转移其实是独立的。即从一行向下移动到另一行时,状态转移与当前行的循环移动次数是无关的。因此:

g[i][j][k] <- f[i-1][j] + k * w + a[i][j`]

而\(f\)的转移即为:

f[i][j] = min(g[i][j][0到m-1])

code

E

交互 + 二分,个人感觉非常不错的一道题。

首先要想明白一点:由于\(1\)的位置不确定,所以每一次询问的真假性也是不确定的。所以要想办法破掉这个牢笼,让每一次询问的真假性得以确定,从而获得有用信息。

假设这段区间中没有1,即为全\(0\)区间,则我们可以知道,0一定是真的回答,1一定是假的回答,因为所有区间的和均为0。这样区间长度与回答之间就具有了二段性:越长的区间回答越容易假,越短的区间回答越容易真。通过二分,就可以在\(O(logn)\)时间内确定出\(k\)。

所以可以考虑:确定出来\(1\)在哪个子区间内,这样其余的区间就全0了。可以利用上述方法确定\(k\)的值。

具体地,可以确定出\(1\)是在整个序列的前一半还是后一半:即为官方题解的做法,通过询问\(2\)次\(1/4\)长度区间方法确定出了\(1\)的分布,自己确实想不到qwq...

同样,对含有\(1\)的那一半区间再询问\(1\)次,即可以确定出\(k\)与\(n/2\)的大小关系。

这样,就将区间分为了两半:一半全\(0\),一半含有一个\(1\)。

此时又分为两种情况:

  1. \(k<=n/2\):直接对长度为\(n/2\)的全0区间二分,原理和上面说的一样。
  2. \(k>n/2\): 由于全\(0\)区间长只有\(n/2\),故只用全\(0\)区间时只能对\(k<=n/2\)的情况进行判断。那么\(k>n/2\)时怎么办呢?有个巧妙的办法:将另一半含1区间和该全0区间的子区间结合,这样构造的区间和一定为\(1\),并且区间长度范围是\([n/2+1,n]\)。这样就转化为了和上述一模一样的做法,同样具有二段性,二分即可。

code

标签:994,code,...,CF,转移,确定,区间,移动,div2
From: https://www.cnblogs.com/jjjxs/p/18660823

相关文章

  • VP Codeforces Round 994 (Div. 2)
    A.MEXDestruction题意:给你一个数组,每次操作选择一个区间使这个区间变为区间mex,问最少操作使得数组全为0.容易发现,对任意一个区间,最多两次操作这个区间就会全变成0,于是我们想尽可能操作大的区间。但并不是直接操作整个数组一定更好,如果我们选择的区间里没有0,那么只需要一次操......
  • Codeforces Round 986 (Div. 2) CF2028 代码集
    CodeforcesRound986(Div.2)CF2028代码集目录CodeforcesRound986(Div.2)CF2028代码集CF2028A-Alice'sAdventuresin''Chess''CF2028B-Alice'sAdventuresinPermutingCF2028C-Alice'sAdventuresinCuttingCakeCF2024D-A......
  • [CF2039G] Shohag Loves Pebae 做题记录
    link高级筛法题。每条路径的条件是很难求的,考虑将其转化。发现对于一条路径,点数为\(c=a\cdotb\),那么其条件是无用的:考虑其包含的所有点数为\(a\)的路径,需要满足这\(c\)个点的权值乘积不被\(a\)整除。进一步的,只有点数为质数的路径条件才有用。对于每个点\(i\),求出......
  • 在 PowerShell 中,您可以使用多个命令来管理和监控电池及电源设置。以下是按功能分类的
     在PowerShell中,您可以使用多个命令来管理和监控电池及电源设置。以下是按功能分类的PowerShell电池相关命令及其描述表格。功能分类命令描述电池状态查询Get-WmiObject-ClassWin32_Battery获取当前电池状态信息,如电池充电状态、剩余电量、设计容量等。......
  • CF2057E2 Another Exercise on Graphs (hard version) 题解
    感觉和[NOI2018]归程有点像(?考虑对每个询问二分答案,设二分到的答案是\(x\),要判断路径上的\(k\)大值是否能不大于\(x\),只需先将价值不大于\(x\)的所有边的边权设为\(0\),其他边设为\(1\),跑一遍\(a\)到\(b\)的最短路,看最短路长度是否不大于\(k\)即可。因为\(x\)的......
  • [题目记录]CF335F Buy One , Get One Free
    CF335FBuyOne,GetOneFree题意\(n\)个物品,价格为\(a_i\),每买一个物品\(i\)可以免费得到一个\(a_j<a_i\)的物品\(j\),问获取所有物品的最小花费.\(n\le5\times10^5\),\(1\lea_i\le10^9\).题解有一个最直接显然的贪心是买最大,送次大,以此类......
  • 题解:CF2043C Sums on Segments
    题意给你一个长度为\(n\)的数组\(a\),满足\(a\)中有且仅有一个不为\(1\)也不为\(-1\)的数(以下简称特殊的值),剩余的数都是\(1\)或\(-1\)。求所有可能的子区间的和的值(下文简称答案)。从小到大一次输出每一个值,每个值只输出一遍。题解首先,我们发现,如果把那个特殊的值考......
  • 605 [CF 609E] Minimum spanning tree for each edge
    //605[CF609E]Minimumspanningtreeforeachedge.cpp:此文件包含"main"函数。程序执行将在此处开始并结束。///*http://oj.daimayuan.top/course/22/problem/981给定一张n个顶点m条边的带权无向简单图,顶点编号从1到n,对于每一条边请求出包含这条边的生成树......
  • 题解:CF2057B Gorilla and the Exam
    CF2057BGorillaandtheExam思路不难发现其实每次操作就是把数组\(a\)内所有值为\(y\)的数都删除掉(\(y\)为数组\(a\)中的莫一个值)。所以我们需要把尽可能多的数都变成原来数组里出现次数最多的数(从出现数量最少的开始,这样能使得消失的数值种类最大化)。首先想到使用数组......
  • CF 139A.Petr and Book(Java实现)
    题目分析    这个题就是看书,给你一本书一共n页,每天看i页,问你第几天看完思路分析    两行输入获取n和i的值,数据处理的逻辑就是不断用n减去i,直到n<=0,同时注意一周七天循环,涉及到取模代码importjava.util.*;publicclassMain{ publicstaticvoidma......