SSY20240816提高组T3题解__备用钥匙__转化+DP

题面

题意描述(有点长, 请耐心阅读)

你知道Just Odd Inventions社吗?这个公司的业务是“只不过是奇妙的发明(Just Odd Inventions)”。这里简称为JOI社。

JOI社有N名员工,编号从1到N。所有员工的工作时间从时刻0持续到时刻M,时刻0和时刻M的时候,所有员工都必须在公司内。

某天,出于巧合,JOI社的每个员工都要出行恰好一次。员工i(1<=i<=N)在时刻Si离开公司,时刻Ti回到公司。同一时刻不会同时有两名以上的员工离开或回到公司。

JOI社的入口处有一扇巨大的门,员工只能通过这扇门离开或回到公司。门上挂着一把锁,从公司内部可以任意开锁或上锁,但从公司外部只有持有备用钥匙的人才能开锁或者上锁。时刻0时,锁是锁上的。

每个社员在回到公司的时候,都必须能够进入公司。换句话说,对于任意1<=i<=N,要么员工i持有备用钥匙,要么时刻Ti时门是开着的,否则是不被允许的。员工回到公司的时候,或者携带备用钥匙的员工离开公司的时候,可以选择锁门或不锁。没有携带备用钥匙的员工离开公司的时候没有办法锁门。 JOI社的社长决定把备用钥匙交给N个员工中的K个人。为了避免钥匙的丢失,员工之间不允许借用钥匙。此外,JOI社的社长很重视时间效率,因此每个员工在离开或回到公司的时刻以外,不允许开锁或者上锁。

出于安全的考虑,社长希望上锁的时间越长越好。现在他将员工出入公司的信息和准备交给员工的钥匙数量告诉了你,请你求出在能使所有员工回到公司的时候都能进入公司的大门的前提下,上锁的时间最长是多少。

输入输出格式

输入格式

第一行三个空格分隔的整数N,M,K,表示JOI社的员工有N个,工作时间从时刻0到时刻M,备用钥匙有K把。 接下来N行,第i行(1<=i<=N)有两个空格分隔的整数Si,Ti,表示员工i在时刻Si离开公司,时刻Ti回到公司。

输出格式

输出一行一个正整数,表示上锁时间总和的最大值。

样例数据

输入数据 1
4 20 2
3 11
5 15
6 10
12 18
输出数据 1
13

提示&样例解释

JOI社共有4名员工,工作时间为时刻0~时刻M,共有两把备用钥匙。 将钥匙交予员工2和员工4,一天日程如下:

时刻0,锁是关闭状态

时刻3,员工1离开公司。由于员工1没有备用钥匙,无法锁门。

时刻5,员工2离开公司,锁门。

时刻6,员工3离开公司。由于员工3没有备用钥匙,无法锁门。

时刻10,员工3回到公司,不锁门。

时刻11,员工1回到公司,锁门。

时刻12,员工4离开公司,锁门。

时刻15,员工2回到公司,锁门。

时刻18,员工4回到公司,锁门。

直到时刻20为止,锁都保持关闭状态。上锁的时间段为0~3,5~6,11~20,总计 ( 3 − 0 ) + ( 6 − 5 ) + ( 20 − 11 ) (3-0)+(6-5)+(20-11) (30)+(65)+(2011)时段,故答案为13。

数据范围

对于100%的数据:
1 ≤ N ≤ 2000 , ∣ ∣ 1 ≤ M ≤ 1 0 9 , ∣ ∣ 1 ≤ k < N , ∣ ∣ 1 ≤ S i < T i < M 1\le N\le 2000,||1\le M\le 10^9,||1\le k<N,||1\le S_i<T_i<M 1N2000,∣∣1M109,∣∣1k<N,∣∣1Si<Ti<M

题解

思路

我们把所有员工的进出时间, 记录在一个数轴上, 每次某个人的出 / / /入操作作为一个点
如下图:
在这里插入图片描述
对于每一个区间(最小区间, 区间内除端点外不含其他点) 的两个端点, 一共有四种情况

  1. 左入右入
  2. 左入右出
  3. 左出右入
  4. 左出右出

现在我们在不考虑其他区间状态      \;\; (或者说假设其他区间门都是开着的)      \;\; 的情况下, 假设当前区间门一直都是上锁的, 需要钥匙的情况

  1. 左入右入
    第一个人进来的时候, 由于门的状态不确定, 所以不一定需要钥匙
    第二个人进来的时候, 根据假设, 门一定是锁着的, 所以它一定需要钥匙
  2. 左入右出
    第一个人进来的时候, 由于门的状态不确定, 所以不一定需要钥匙
    第二个人出去的时候, 门可以从内部解锁, 所以它不一定需要钥匙
  3. 左出右入
    第一个人出去的时候, 根据假设, 一定需要从外面锁门, 所以一定需要钥匙
    第二个人进来的时候, 门一定是锁着的, 所以它也一定需要钥匙
  4. 左出右出
    第一个人出去的时候, 根据假设, 一定需要从外面锁门, 所以一定需要钥匙
    第二个人出去的时候, 门可以在内部解锁, 所以它不一定需要钥匙

现在设这段区间长度为 t i m e time time, 我们发现,


对于 2 2 2情况, 这段区间的贡献是一定成立的, 无论这个区间的前后区间是打开的还是锁上的 (请自行枚举证明)

对于 1 , 4 1,4 1,4情况, 这段区间能否产生贡献 (能否一直上锁) 只依赖于其中的一个人 (就是一定要拿钥匙的那个人) . 因此我们把这一段的贡献加到这个人身上 (点权)

对于 3 3 3情况, 这段区间能否产生贡献同时依赖于两个人 (必须两个人同时拿着钥匙才能有贡献) , 因此我们把这两个人连边, 并且单开一个数组 e d g e [ i ] edge[i] edge[i], 表示这两个点所代表的两个人同时拥有钥匙时产生的贡献 (边权)

对于一种特殊情况, 左右端点代表同一个人, 我们就把贡献加到这个人身上 (点权)


这样"加工"完后, 我们发现, 由于每一个人最多被连了两给边(它的出 / / /入都作为某个 3 3 3情况的出 / / /入), 最后的图一定是由若干条链组成的 (请自行枚举证明).
我们把这些链拼在一起 (链和链之间边权为 0 0 0), 重新编号, 就变成了下面的题目

现在有 n n n个点, n − 1 n-1 n1条边, 满足给的图时一个链, 每个点有权值 a i a_i ai, 在其中选取 k k k个点, 如果选取了相临的两个点, 就回额外产生贡献 e d g e i edge_i edgei, 求产生贡献的最大值

现在就可以 d p dp dp
定义一个方程式 d p [ i ] [ j ] dp[i][j] dp[i][j]表示现在枚举到了第 i i i个点, 且在 i i i点使用钥匙, 已经用了 j j j把钥匙, 产生贡献的最大值

转移还是很好想的
d p [ i ] [ j ] = m a x ( d p [ k ] [ j − 1 ] ,    d p [ i − 1 ] [ j − 1 ] + e d g e i − 1 ) + a [ i ] ( 1 ≤ k ≤ i − 2 ) dp[i][j]=max(dp[k][j-1],\;dp[i-1][j-1]+edge_{i-1})+a[i](1\le k\le i-2) dp[i][j]=max(dp[k][j1],dp[i1][j1]+edgei1)+a[i](1ki2)
但是, 这样转移会 T L E TLE TLE, 原因就是枚举 k k k, 求其最大值的过程过慢
我们可以额外记录一个数组 g [ i ] [ j ] g[i][j] g[i][j], 表示 f [ 1 ] [ j ] f[1][j] f[1][j] f [ i ] [ j ] f[i][j] f[i][j]的最大值
最后的时间复杂度为 O ( n k ) O(nk) O(nk)
完美 ! 完美! 完美!

AC Code

先欠着, 明天再给

  • 16
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 这个错误是因为 `legend` 函数的第一个输入参数 `ssy{1}` 和第二个输入参数 `ssy{2}` 的类型不正确导致的。`ssy` 可能是一个单独的数,而不是一个包含两个数的单元格数。请确保 `ssy` 是一个单元格数,并且包含两个数。你可以使用 `celldisp(ssy)` 查看 `ssy` 的类型和内容,以确保它符合要求。如果 `ssy` 不包含两个数,则需要修改代码以正确设置 `ssy` 的值。 ### 回答2: 这段代码出错的原因可能是在第31行的legend函数中的参数配置有误。根据给出的代码,legend函数应该是用于添加图例的。根据我对legend函数的了解,它的参数应该是一个字符串数,可以用于标识图中的每个数据系列。 在这个具体的错误中,可能是ssy这个变量没有被正确地定义或者存在问题。可以先检查一下代码前面是否有对ssy的定义,或者看一下ssy的数据类型是否正确。另外,在legend函数的参数中,0.2和0.3这两个数值可能是指定图例的位置或者大小,也可以检查一下这些数值是否符合函数的要求。 总之,确定代码中的ssy变量是否正确定义,并检查legend函数的参数是否符合函数要求,可以帮助解决这个错误。如果还有其他代码和错误信息提供,我们可以进行更准确的分析和回答。 ### 回答3: 在图表绘制过程中,调用了函数 legend(),并传入了参数 ssy{1}、ssy{2}、0.2和0.3。然而,在第31行中,函数调用出现了错误,导致程序无法正常执行下去。 出现错误的原因可能有多种可能性。首先,可能是因为函数 legend() 在当前环境中未定义或未正确加载,导致调用失败。此外,还有可能是传入的参数有误,比如 ssy{1} 和 ssy{2} 可能不存在或者数据类型不匹配。还有一种可能是传入的透明度参数0.2和0.3超出了函数允许的范围,导致错误。 为了解决这个问题,我们可以尝试以下几个步骤。首先,确认函数 legend() 是否在当前环境中正确加载,可以查看相关的库是否被正确导入。如果没有正确加载,需要加载相关的库或更新软件版本。其次,检查变量 ssy{1} 和 ssy{2} 是否存在或数据类型是否正确,可以使用打印语句或调试工具来检查变量的值和类型。最后,可以尝试更改透明度参数的值,确保其在合理的范围内。 总之,出现 sigma_masi_0707 (第 31 行) legend(ssy{1},ssy{2},0.2,0.3) 的错误可能是由函数未定义或加载失败、参数传递错误或透明度超出范围等原因引起的。通过逐步排除可能的问题,并针对性地进行修复,可以解决这个错误。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值