惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园_首页
博客园 - 【当耐特】
博客园 - 叶小钗
阮一峰的网络日志
阮一峰的网络日志
WordPress大学
WordPress大学
D
Docker
T
The Blog of Author Tim Ferriss
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Microsoft Azure Blog
Microsoft Azure Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
月光博客
月光博客
M
MIT News - Artificial intelligence
H
Hackread – Cybersecurity News, Data Breaches, AI and More
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
云风的 BLOG
云风的 BLOG
F
Fortinet All Blogs
罗磊的独立博客
小众软件
小众软件
A
About on SuperTechFans
MyScale Blog
MyScale Blog
D
DataBreaches.Net
The GitHub Blog
The GitHub Blog
C
Check Point Blog
L
LangChain Blog

Makerlife 的小站

2025-2026 赛季 游记 && 退役记 NOIP 2024 游记 集训记录 CSP2024 游记 板子库 动态规划 刷题记录 杂题乱记 数学期望 学习笔记 数论 学习笔记 CF1000F One Occurrence 题解 P6878 [JOI 2020 Final] JJOOII 2 题解 CSP2023 游寄 主定理 CF1695C Zero Path 题解 字符串算法全家桶 学习笔记 2023.06.03 模拟赛 Azure for Students 使用指北 AT_ABC286C 题解 洛谷 AT1898 题解 洛谷 CF1036A 题解 洛谷 CF1040A 题解 洛谷 SP3591 题解 洛谷 AT278 题解 洛谷 CF141B 题解 洛谷 AT2561 题解 洛谷 AT3525 题解 洛谷 CF899B 题解 洛谷 AT4787 题解 洛谷 AT4810 题解 洛谷 SP5450 题解
AT_ABC306D 题解
Makerlife · 2023-06-21 · via Makerlife 的小站

Problem Link

很简单的一道 D 题。

Explanation

高桥君要在餐厅里吃一份由 nn 道菜组成的奇怪的全套菜单,每道菜都有一个美味程度 yiy_i,但是有的菜含有毒素,有的菜含有解毒剂。高桥君可以选择吃或者不吃每道菜,但是如果他吃了毒素,他会拉肚子,如果他拉肚子时再吃毒素,他会死亡。高桥君必须活着离开餐厅,求他能够得到的最大的美味程度之和。

Solution

很显然这是一道 DP 题。

fi,1/0f_{i,1/0} 表示吃到第 ii 道菜时,当前是否中毒的最大美味值

接下来分类讨论:

  • 如果当前这一步为无毒,即 xi=0x_i=0 时:

    • 考虑 fi,1f_{i,1}:要想保持中毒状态,当前这一步一定不能吃,即 fi,1=fi−1,1f_{i,1}=f_{i-1,1}

    • 否则,考虑 fi,0f_{i,0}:要想在这一步吃完不是中毒状态,有两种可能:

      1. 前一步本来就不是中毒状态,那直接取当前吃与不吃的最大值即可,即 fi,0=max⁡(fi−1,0,fi−1,0+yi)f_{i,0}=\max(f_{i-1,0},f_{i-1,0}+y_i)
      2. 前一步是中毒状态,那这一步必须吃,才能使吃完后状态为无毒,即 fi,0=fi−1,1+yif_{i,0}=f_{i-1,1}+y_i

      所以,综合一下上式,fi,0=max⁡(fi−1,0,fi−1,0+yi,fi−1,1+yi)f_{i,0}=\max(f_{i-1,0},f_{i-1,0}+y_i,f_{i-1,1}+y_i)

  • 否则,如果当前这一步有毒,即 xi=1x_i=1 时:

    • 仍然像之前一样,先考虑 fi,1f_{i,1} 情况:也就是这一步吃完时中毒状态,出现两种可能:

      1. 之前本来就中毒,这一步没有吃,注意,没有之前中毒,这一步还吃的状态,因为这样会使高桥死亡,fi,1=fi−1,1f_{i,1}=f_{i-1,1}

      2. 当然,也有可能之前没有中毒,吃了以后中毒了,也就是 fi,1=fi−1,0+yif_{i,1}=f_{i-1,0}+y_i

      综合一下,就是 fi,1=max⁡(fi−1,1,fi−1,0+yi)f_{i,1}=\max(f_{i-1,1},f_{i-1,0}+y_i)

    • 接着考虑 f1,0f_{1,0}:要想当前不中毒,只能不吃当前这一步。即 fi,0=fi−1,0f_{i,0}=f_{i-1,0}


结论如下;

xi=0x_i=0 时:

{fi,0=max⁡(fi−1,0,fi−1,0+yi,fi−1,1+yi)fi,1=fi−1,1\begin{cases} f_{i,0}=\max(f_{i-1,0},f_{i-1,0}+y_i,f_{i-1,1}+y_i)\\ f_{i,1}=f_{i-1,1} \end{cases}

xi=1x_i=1 时:

{fi,0=fi−1,0fi,1=max⁡(fi−1,1,fi−1,0+yi)\begin{cases} f_{i,0}=f_{i-1,0}\\ f_{i,1}=\max(f_{i-1,1},f_{i-1,0}+y_i) \end{cases}

最后输出 max⁡(fn,0,fn,1)\max(f_{n,0},f_{n,1}) 即可。

Core Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
f[0][0]=f[0][1]=0;
for(int i=1;i<=n;i++)
{
if(x[i]==1)
{
f[i][1]=max(f[i-1][1],f[i-1][0]+y[i]);
f[i][0]=f[i-1][0];
}
else
{
f[i][1]=f[i-1][1];
f[i][0]=max(f[i-1][1]+y[i],max(f[i-1][0]+y[i],f[i-1][0]));
}
}
write(max(f[n][0],f[n][1]));