首页 > 其他分享 >luogu P8497 [NOI2022] 移除石子

luogu P8497 [NOI2022] 移除石子

时间:2023-06-01 20:55:09浏览次数:51  
标签:luogu 复杂度 石子 个数 满足 NOI2022 移除 区间 dp

题面传送门

不好评价?

首先我们考虑最基础的情况,当 \(k=0,l_i=r_i\) 时,相当于我们需要判定一个状态能不能被消完。

这相当于我们要执行若干次 \(2\) 操作,使得每个位置要么大于等于 \(2\),要么为 \(0\)。为此我们需要挖掘一些操作 \(2\) 的性质。

性质 \(1\):操作区间长度不会超过 \(5\)

因为如果大于等于 \(6\) 就一定能拆成更小的区间。

性质 \(2\):对于每个点,以这个点为结尾的区间个数和以这个点为开头的区间个数都不会超过 \(2\),并且不会是长度为 \(4\) 与 \(5\) 的区间

假设有三个区间,则一定是 \(3,4,5\),那么将 \(4,5\) 的左端点用一次二操作,则 \(4,5\) 变成后一个点的 \(3,4\),这一定更优。

性质 \(3\):对于每个点,经过这个点的区间个数不会超过 \(3\)

我也不会证明……但是有了前两个结论写个暴力搜一搜应该是容易的吧!

于是我们大概就可以写出一个 dp 了。设 \(dp_{i,j,k}\) 表示到了第 \(i\) 个点,经过第 \(i\) 个点的区间个数为 \(j\),以第 \(i\) 个点为开头的区间个数为 \(k\),有没有一种可能。则这个应该满足 \(k\leq j,k\leq 2,j\leq 3\) ,转移应该是平凡的,时间复杂度 \(O(n)\)。

再考虑到 \(k> 0\) 的情况,一种暴力的 dp 就是再加一维,复杂度变成 \(O(nk^2)\)。

虽然能过了,但是我们还是来尝试优化一下。

我们猜想,当 \(a_i\geq b\) 的时候都是等价的,其中 \(b\) 是一个小常数。因为经过一个点的区间个数不超过 \(3\),而再把这个点消掉需要至少两个,因此 \(b\) 的一个下界是 \(6\),这已经很优秀了,但是实际上 \(b\) 是可以取到 \(5\) 的,不过差不多(

所以每个点放的个数不超过 \(b\),复杂度优化到 \(O(nk)\)。

另一个优化的角度是值和状态互换。如果放的石子数满足,当放 \(k\) 个石子可以 win时,放 \(k+1\) 个石子也可以满足,那么我们可以令 \(dp_{i,j,k}\) 为使用石子数的最小值,这样复杂度就是 \(O(n)\) 的。但是这满不满足呢?

当 \(k=0\) 的时候显然是满足的,当 \(k=1\) 的时候有两种情况不满足:全 \(0\),或者 \(n=3\) 且全 \(1\)。

当 \(k\geq 2\) 的时候,只需要考虑 \(k=1\) 的两种不满足情况。全 \(0\) 显然不会出现,如果 \(n=3\) 且全 \(1\) 我们就可以放成两个 \(2\) 一个 \(0\)。因此对于 \(k\geq 2\) 都是满足的。 \(k=1\) 的情况特判就行。

状态看上去不是很多,之后就是套路 dp 套 dp 了。如果按照第一种方法压状态在 \(k=100\) 的时候大概是 \(5\times 10^4\) 个状态,光把这些东西搜出来就 T 了。按照第二种方法搜大概是 \(1.2\times 10^4\) 个状态,时间复杂度 \(O(TnS(n))\),卡卡常就能过。

submission

标签:luogu,复杂度,石子,个数,满足,NOI2022,移除,区间,dp
From: https://www.cnblogs.com/275307894a/p/17450195.html

相关文章

  • 移除元素
     给你一个数组nums 和一个值val,你需要原地移除所有数值等于 val 的元素,并返回移除后数组的新长度。不要使用额外的数组空间,你必须仅使用O(1)额外空间并原地修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。 说明:为什么返回数值是......
  • Luogu P1007 独木桥
    题目描述link思路找到独木桥的中间位置,最少时间考虑在端点左侧的,向左走,在端点右侧的向右走.最多时间考虑在端点左侧的向右走,在端点右侧的向左走.最少时间即为最优情况下最多的时间,最多时间即为最差情况下的最多时间Code#include<cstdio>#include<algorithm>......
  • Luogu P1008 三连击
    题目描述link思路因为\(1-9\)且不能重复使用,所以从\(123\)循环至\(789\),相应的\(2\)倍,\(3\)倍,即为另两个数字.对每个数字进行拆分,所用数字使用次数\(+1\),判断是否每个数字都被使用且只使用一次,输出即可.Code#include<cstdio>#include<cstring>i......
  • 移除链表元素
    代码随想录中的一道基础算法题,这里记录下设置一个虚拟头结点在进行删除操作通过设置虚拟头节点,原链表的所有节点就都可以按照统一的方式进行移除了。classSolution{public:ListNode*removeElements(ListNode*head,intval){ListNode*dummyHead=new......
  • C# 程序开发中如何移除List集合的某列(属性)呢?
    如题,在C#&.NET,.NETCore程序开发中如何移除List集合的某列(属性)呢?比如,有以下的MyClass类: publicclassMyClass{publicintColumn1{get;set;}publicstringColumn2{get;set;}publicintColumn3{get;set;}}现在MyClass的集合myList,如何......
  • 移除LauncherJ界面搜索栏
    修改文档:packages/apps/Launcher3/src/com/android/launcher3/config/FeatureFlags.java ......
  • 最小生成树_LuoguP1669
    P1669P1669[USACO04DEC]BadCowtractorsS题目传送门题意简化:在一个有\(N\)个点\(M\)条边的图中选出\(N-1\)条边构成一棵树,使得树的总边权最大,求最大总边权。上述问题即为最小(大)生成树问题,本题为最大生成树,如有未详者可以移步P3366。该问题一般是Kruskal和Prim......
  • 移除不需要的apk
    注意区分:隐藏launcher界面appicon1.移除不需要的apk:直接修改device.mk文档,去除不编译的apk,系统代码编译时不会将此apk编译进系统,也就是说,不仅设备launcher界面找不到改apk,设置--所有应用下也找不到改apk2.隐藏launcher界面appicon,此修改只是在launcher界面隐藏了app图......
  • Java8 List集合如何移除满足条件的元素
    1.移除List<String>中指定元素for(inti=assSupplementList.size()-1;i>=0;i--){TypgHouseOrderAssessmentSupplementitem=assSupplementList.get(i);if(item.getBzx().contains("新建房屋")){ass......
  • 【LeetCode】203. 移除链表元素
    203.移除链表元素思路一:直接删除法(迭代)1.从头结点开始向后遍历,找到等于val的结点;2.假设cur->val=val,那么要让cur的前一个结点prev的next指针指向cur的下一个结点,即prev->next=cur->next。要注意的是当头结点的值等于val时(head->val=val),因为头节点没有前一个结点,所以可......