190Div2-线性DP+数学思维题+状压DP

1986 字
10 分钟
190Div2-线性DP+数学思维题+状压DP

190Div2#

Dashboard - Educational Codeforces Round 190 (Rated for Div. 2) - Codeforces

Easy: A

Mid: B、C

Hard: D

A-模拟

题意:

n个学生有两种买票方式,其一是每个人付费a,其二是最多润许三人的团体费用b

题解:

对比如下三种选择的花费即可:

1:为每个人采用方案一,总花费cost1 = a*n

2:为所有完整的三人小组购买方案二,剩余的人购买方案一,总花费cost2 = (n%3)*a + (n//3)*b

3:全部购买方案二,总花费cost3 = (n//3 + 1)*b

模拟
for _ in range(int(input())):
n, a, b = map(int, input().split())
cost1 = n * a
cost2 = -(-n // 3) * b
q = n // 3
r = n % 3
cost3 = q * b + min(r * a, b)
print(min(cost1, cost2, cost3))
B-dp/贪心

题意:

给定一个仅包含1~4的字符串s

求删掉的最小个数,使得按顺序从s中获取长度为2的子序列拼成的数字不能被4整除

题解:

显然的原字符串中4是必须删去的

此外,能被4整除的序列还有12和32

设计dp13dp2

遍历字符c,如果字符为'2',那么当前字符只能加到'2'后面,dp2 += 1;如果字符为'3'或者'1',那么该字符可以加到'2'后面,也可以加到'1,3'后面,取二者的最大值:dp13 = max(dp2,dp3) + 1

那么剩下的最大的合法长度就是max(dp13,dp2)

dp
for _ in range(int(input())):
s = list(input().strip())
ss = []
ans = 0
for ch in s:
if ch == '4':
ans += 1
else:
ss.append(ch)
dp2 = dp3 = 0
for x in ss:
# 如果当前这个 '2' 想要加入到后面的 '1, 3' 阵营是不行的(会变成 12 或 32)
# 所以只能更新纯 '2' 的长度
if x == '2':
dp2 += 1
# '1' 或 '3' 可以接在当前的纯 '2' 后面,也可以接在已有的 '1, 3' 后面
# 我们取两者的最大值,加 1
else:
dp3 = max(dp2,dp3) + 1
# 剩下的最大的合法长度
rem = max(dp2,dp3)
ans += (len(ss) - rem)
print(ans)
C-数学思维题

题意:

n张牌,第n张牌有c

选择需要从所有牌中至少取出3张将取出的牌排成圆圈满足:

任意连续的三张牌中,至少有两张牌的数字相同

求最大的取牌数

题解:

XXX1XX1XX1XXYY1YYY

对于每一个数量≥2的牌,为了包裹k个1,需要(k+1)对XX

x ≥ 2*(k+1)

所以其能够包裹的最大的单独为1的个数为:x//2 - 1

特殊情况:

若只有一种≥2的牌,则最大包裹个数为x//2

根据计算出的最大包裹的1个数,用总数减去该数即为答案

数学思维题
t = int(input())
for _ in range(t):
n = int(input())
c = list(map(int,input().split()))
s = sum(c)
one = st = 0
for x in c:
if x == 1:
one += 1
else:
st += x//2 - 1
if one == n - 1:
st += 1
wast = max(0,one - st)
if s - wast < 3:
print(0)
else:
print(s - wast)
D-状压DP(题解来自gemini3.5)

题意:

给定两个城市在nn天内各自播放的剧集序列aabb。两人需选择一个连续区间[L,R][L, R],要求在此期间每一天两人必须满足:要么同时观看同一集,要么同时什么都不看。初始进度均为 0,且必须按顺序观看。求满足此条件的区间[L,R][L, R]** 的总数。** ​

题解:

这道题本质上是一个基于动态规划的区间计数问题,结合了贪心与逆向思维。其核心在于:如何在一个O(N)O(N)的时间内,快速计算出每一个左端点ii 所能延伸到的最远合法右端点。

以下是详细的题解思路:

1. 问题模型抽象

我们要统计所有满足条件的区间[L,R][L, R]。一个区间合法,当且仅当:

  • 同步性:区间内每一天,两人要么看同一集,要么都不看。
  • 进度一致:如果这一天他们看剧,那必须是他们当前看过的下一集。
  • 不剧透:两人在区间内的任何时刻,进度都必须严格一致。如果某一天两地放的剧集不同,且其中一人看了剧,就会导致进度不同步或剧透。

2. 为什么选择逆向遍历?

如果我们从左向右扫描,很难判断当前区间是否会因为后面的某一天而失效。

如果我们从后向前(从n1n-100)遍历,对于每一个起始位置ii

  • 我们维护pa[x]pb[x]:分别记录剧集xx在 Alice 和 Bob 的城市中,在当前索引ii** 及其之后**第一次出现的位置。
  • 我们可以实时知道:如果从ii开始看剧,下一集x+1x+1 在两地分别会在哪里出现。

3. 核心动态规划状态:dp[i]

我们需要定义一个状态dp[i]如果两人在索引ii** 处刚好一起看完了同一集(且该集之后要看的是下一集),那么这个同步状态能向右无剧透延伸到的最远右边界。** ​

状态转移逻辑:#

假设在位置ii处,a[i]==b[i]==xa[i] == b[i] == x(两人同步看了第xx集),那么下一集是x+1x+1

  • 情形 1:下一集在两地出现的位置相同 (pa[x+1] == pb[x+1])

    这意味着从iipa[x+1]pa[x+1]之间,两人都是“不看剧”或者“同步看剧”的状态。因此,当前同步状态可以无缝衔接跳转到pa[x+1]pa[x+1] 处继续,状态转移为:

    dp[i]=dp[pa[x+1]]dp[i] = dp[pa[x+1]]
  • 情形 2:下一集在两地出现的位置不同 (pa[x+1] != pb[x+1])

    这意味着两人在向右扩展的过程中,其中一个人会先看到下一集,而另一个人还没看到。为了不剧透,他们在这个区间内无法继续看下一集,最远只能延伸到两地中先出现那一集的位置(因为到了那个点,先看到的人就会看剧,而另一个人没看到,导致失效)。

    dp[i]=min(pa[x+1],pb[x+1])dp[i] = \min(pa[x+1], pb[x+1])

4. 统计答案 (累加贡献)

在遍历到位置ii时,我们要计算有多少合法的右端点RR

  • 如果第 1 集(编号 0)在两地的第一次出现位置不同 (pa[0] != pb[0]):

    说明两人还没开始看剧,或者第一集还没对上。此时,在两地第一次出现第一集之前,两人都是“摆烂”状态(什么都不看),这期间的所有日子都可以作为合法的右端点。

    合法右端点范围:[i,min(pa[0],pb[0])1][i, \min(pa[0], pb[0]) - 1]

    贡献:min(pa[0], pb[0]) - i

  • 如果两地第一次出现第一集的位置相同 (pa[0] == pb[0]):

    说明两人可以在这里同步看第一集。于是我们可以直接跳转到该位置对应的最大延伸点dp[pa[0]]

    合法右端点范围:[i,dp[pa[0]]1][i, dp[pa[0]] - 1]

    贡献:dp[pa[0]] - i

状压DP
for _ in range(int(input())):
n = int(input())
a = [int(x) - 1 for x in input().split()]
b = [int(x) - 1 for x in input().split()]
# pa[x] 记录剧集 x 在 a 中的位置,pb[x] 同理
# 初始化为 n,表示未出现
pa = [n] * (n + 1)
pb = [n] * (n + 1)
dp = [n] * (n + 1)
ans = 0
# 从后往前遍历
for i in range(n-1, -1, -1):
pa[a[i]] = i
pb[b[i]] = i
# 如果这一天两人看同一集
if a[i] == b[i]:
x = a[i] + 1
# 如果下一集在两人城市中出现位置相同,则继承该位置的 dp 状态
if pa[x] == pb[x]:
dp[i] = dp[pa[x]]
else:
# 否则,能走到的最远距离受限于两者中先出现的位置
dp[i] = min(pa[x], pb[x])
# 统计答案
# 如果第 0 集(即原始编号 1)在两地的位置不同,说明区间 [i, min(pa[0], pb[0]) - 1] 是合法的
if pa[0] != pb[0]:
ans += min(pa[0], pb[0]) - i
else:
# 否则,利用 dp 数组跳转到下一次同步的终点
ans += dp[pa[0]] - i
print(ans)
190Div2-线性DP+数学思维题+状压DP
http://blog.7a7a68.xyz/posts/190div2/
作者
Waning
发布于
2026-05-20
许可协议
CC BY-NC-SA 4.0
Profile Image of the Author
Waning
愿你明日如绚丽之花.
公告
还活着.
音乐
封面

音乐

暂未播放

0:00 0:00
暂无歌词
分类
标签
站点统计
文章
56
分类
8
标签
20
总字数
125,693
运行时长
0
最后活动
0 天前

目录