问题 G: Bob和Alice(3)
内存限制:128 MB时间限制:1.000 S评测方式:文本比较
题目描述
求的是最大值!!!
Bob和Alice在玩一个序列游戏
有一个n-1个数的序列
B1 B2 ....... Bn−1
Bob又定义了一个新的序列
A1 A2 .......An
对每一个i [1 <= i <= n - 1]
Bi>=max(Ai,Ai+1)
好奇的Alice想知道A序列在这样的约束之下
A序列的总和的最大值是多少
即求max∑i=1nan ;
输入
n
B1 B2 .......Bn−1
2 <= n <= 100
0 <= Bi <= 105
输出
A序列的总和的最大值是多少
样例输入
6
0 153 10 10 23
样例输出
53
题解:
我认为这道题最重要的点还是在于读题,读完题之后,我们知道要求A整个序列的最大值.
B数组是肯定要建,但不一定需要创建A数组去解决本题。
为什么呢?
因为与其说是在找A的max(Ai,Ai+1),倒不如说是在找B的Bi,Bi+1大小关系。换言之,既然求的并非A中单个元素,而是整个A序列的最大总和,那么我们就可以抽象为通过判断B的Bi,Bi+1大小关系来判断加和的多少;
我们可以先画一张图,就拿测试用例来说:
![](https://i-blog.csdnimg.cn/blog_migrate/705f8803df2717175ed689fb2e1ba994.png)
三角形表示了Bi对于Ai,Ai+1的对应关系,那么我们发现,如果我们要使的A6最大,只需要填B5也就是23即可,因为它的大小只由一个三角形对应;但如果我们要使得A5最大,就要考虑两个三角形也就是两层对应关系。这两层对应关系并非毫无关联,因为我们发现它取决于B4和B5的大小关系,如下图所示:
![](https://i-blog.csdnimg.cn/blog_migrate/c9c3cd175d2e784c8810c99ac1a77ecc.png)
因为10<23,所以A5里面我们可以放心的填入10。所以也就是说当B[i]<=B[i+1]时,A[i+1]就等于B[i];之所以说必须是当B[i]<=B[i+1]时,是因为还有如图所示的情况发生:
![](https://i-blog.csdnimg.cn/blog_migrate/2e4914ac4a1d5b58e0243b8f514fec60.png)
B2=153>B3,当B[i]>B[i+1]时,我们不能在A[i+1]里填入B[i],假设我们填入153就和前面一个三角形冲突了,使得B3<A3,而这明显是不符合定义的。但我们可以填入A[i+2](==B[i+1])。
所以我们只需要让两个三角形其实也就是B[i]和B[i+1]的大小关系解决好中间部分的迭代求和,剩下的A[0]和A[n]显然很好处理,处理完加上去就可以。给出AC代码如下:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
#include<cmath>
#include<vector>
using namespace std;
int main()
{
int n, B[100] = { 0 }, temp;
cin >> n;
if (n == 2)//处理掉n-3会出界的问题.
{
cin >> temp;
cout << 2 * temp << endl;
exit(0);
}
for (int i = 0; i < n - 1; ++i)
{
cin >> B[i];
}
int sum = B[n - 2];
for (int i = n - 3; i >= 0; --i)
{
if (i != 0)
{
if (B[i] > B[i + 1])
sum += B[i + 1];
else if (B[i] <= B[i + 1])
sum += B[i];
}
else
{
if (B[i] <= B[i + 1])
sum += 2 * B[i];
else
sum += B[0]+B[1];
}
}
cout << sum << endl;
return 0;
}