Toyota Programming Contest 2023#3(AtCoder Beginner Contest 306) 6月17日比赛 第四题

news/2025/2/13 4:54:08/

  • 题目地址:D - Poisonous Full-Course

题目大意

时间限制:2秒,空间限制:1024MB,分值:400分

问题描述

小明来到了一家餐厅,一共有N道菜,第i道菜具有以下属性:

  • X_{i}= 0,则这道菜是无毒的,且吃了它会得到Y_{i}的美味值
  • X_{i}= 1,则这道菜是有毒的,但吃了它同样会得到Y_{i}的美味值

最初,小明的胃是健康的。当小明吃了一道菜后,他会:

  • 当他的胃是健康的
    • 若这道菜无毒,则他的胃依然健康
    • 若这道菜有毒,他就会得胃病
  • 当他得了胃病
    • 若这道菜无毒,则他的胃就会变得健康
    • 若这道菜有毒,他就会死

现在,小明面前将依次展示第1道菜,……,直到第N道菜展示完毕为止。对于每道菜,小明可以选择吃或者不吃。选择吃就可能会改变状态并增加(减少)美味值;若选择不吃,则状态与美味值都不会有变化。

现在,我们要让小明活着走出餐厅,请问小明能获得的最大美味值是多少?

数据规模

  • 每个值都是整数
  • 1\leq N\leq 3\times 10^{5}
  • X_{i}\in \left \{ 0,1\right \} (言外之意,x_{i}不是0就是1)
  • -10^9 \leq Y_i \leq 10^9

输入

输入来自标准输入,其格式如下:

N

X_1   Y_1

X_2   Y_2

X_N   Y_N

输出

输出一个整数,表示答案。


输入样例1

5
1 100
1 300
0 -200
1 500
1 300

输出样例1

600

样例解释:

以下选择使小明获得了最大的美味值(即600)且未死亡:

  •  他选择跳过第一道菜,现在他的胃是健康的,共获得了0美味值;
  •  他选择享用第二道菜,现在他的胃不是健康的,共获得了300美味值;
  •  他选择享用第三道菜,现在他的胃是健康的,共获得了100美味值;
  •  他选择享用第四道菜,现在他的胃不是健康的,共获得了600美味值;
  •  他选择跳过第五道菜,现在他的胃不是健康的;
  • 最终他获得了600美味值并活着走出了餐厅。

输入样例2

4
0 -1
1 -2
0 -3
1 -4

输出样例2

0

在这组样例中,他能获得的最大美味值为0。

输入样例3

15
1 900000000
0 600000000
1 -300000000
0 -700000000
1 200000000
1 300000000
0 -600000000
1 -900000000
1 600000000
1 -100000000
1 -400000000
0 900000000
0 200000000
1 -500000000
1 900000000

输出样例3

4100000000

答案不一定是32位整数。


这道题,明显是一个dp。

如果我们定义dp[i][0]表示吃完前i个菜之后胃依然健康,获得的最大美味值;dp[i][1]表示吃完前i个菜之后得了胃病,获得的最大美味值。那么:

dp[i][0]有四种情况:0,dp[i-1][0]+y[i],dp[i-1][1]+y[i](前提:x[i]==0),dp[i-1][0]

dp[i][1]只有三种情况:0,dp[i-1][0]+y(前提:x[i]==1),dp[i-1][1]

到最后,能获得的最大美味值就是max(dp[n][0],dp[n][1])。

#include <iostream>
using namespace std;
typedef long long int ll;
ll n, dp[300005][2];
int main() {cin >> n;ll x, y;for (int i = 1; i <= n; i++) {cin >> x >> y;if (x == 0) {dp[i][0] = max(dp[i][0], max(dp[i - 1][0] + y, dp[i - 1][1] + y));}else {dp[i][1] = max(dp[i][1], dp[i - 1][0] + y);}dp[i][0] = max(dp[i][0], dp[i - 1][0]);dp[i][1] = max(dp[i][1], dp[i - 1][1]);}cout << max(dp[n][0], dp[n][1]) << endl;return 0;
}

当然这个代码还可以再优化一下空间复杂度:

#include <iostream>
using namespace std;
typedef long long int ll;
ll n;
int main() {cin >> n;ll p0 = 0, p1 = 0;ll x, y;for (int i = 1; i <= n; ++i) {cin >> x >> y;if (x == 0) {p0 = max(p0, max(p0 + y, p1 + y));}else {p1 = max(p1, p0 + y);}}cout << max(p1, p0) << endl;
}

轻松搞定!


http://www.ppmy.cn/news/497346.html

相关文章

联想thinkbook 关掉fn键,方便调试程序

进入bios&#xff1a;fn f12,出现联想logo界面时按这个组合键 在进入的bios界面设置关闭功能键&#xff0c;也就是取消笔记本fn键。首先&#xff0c;要按tab翻页&#xff0c;找到setup回车进入bois。其次&#xff0c;是开机时进入bios后找到config界面。第三&#xff0c;是在c…

C/C++ Linux 键盘检测

一、方法 C/C 在 Linux 中没有现成的键盘检测函数&#xff0c;可以利用 <termio.h> 中的 struct termios 结构体来构造键盘检测函数。至于 struct termios 的具体解析&#xff0c;这里不展开介绍&#xff0c;下面给出构造的键盘检测代码。 二、代码 #include <termi…

联想键盘 F1 -12 键不能用解决

http://www.zfnn.com/post/706.html Wednesday, 2011-3-16 16:24:30 联想键盘F1-F12键咋不用起来了 换了一个新键盘&#xff0c;联想的。 突然发现F1-F12键失效&#xff0c;差点重装系统。 几经折腾&#xff0c;才发现这个联想新键盘有一个Fn键&#xff0c;如果想正常使用FI至…

C语言丨关键字union的定义和使用

union&#xff0c;中文名“联合体、共用体”&#xff0c;在某种程度上类似结构体struct的一种数据结构&#xff0c;共用体(union)和结构体(struct)同样可以包含很多种数据类型和变量。 但在“联合”中, 各成员共享一段内存空间, 一个联合变量的长度等于各成员中最长的长度 。一…

蓝牙键盘无法连接 ,win10要求输入pin码可是却不显示pin码

解决方案&#xff1a;打开“设备和打印机”&#xff0c;切换到在设备上输入密码就可以显示PIN码。

c++字符前面的L和_T

c字符前面的L和_T 字符串前面加L表示该字符串是Unicode字符串。 _T是一个宏&#xff0c;如果项目使用了Unicode字符集&#xff08;定义了UNICODE宏&#xff09;&#xff0c;则自动在字符串前面加上L&#xff0c;否则字符串不变。因此&#xff0c;Visual C里边定义字符串的时候&…

关于C++中四字节对齐的坑

最近做一个工程&#xff0c;大体的意思是在程序中定义一个结构&#xff0c;运行中会将结构直接写到文件中&#xff0c;然后另一个程序会用同样的结构读出来。为了验证是写文件的程序的问题还是读文件的程序的问题&#xff0c;用winhex来打开文件&#xff0c;仿照结构体定义写tp…

C/C++ union联合体你绝对不知道的知识

union的特点和性质我们不再介绍&#xff0c;我们讲一些UB的东西 #include<iostream> union Test {int a;double b;char ch; }t; int main() {t.b 12000.0;t.a 13;printf("%d\n", t);printf("%lf\n", t);printf("%zd\n", sizeof(t));prin…