D - Wandering
Time Limit: 2 sec / Memory Limit: 1024 MB
Score : 400 points
Problem Statement
Given is a number sequence A1,A2,A3,…,AN, which may contain negative elements.
On a number line, there is a robot at coordinate 0. It will do the following actions in order:
-
Move A1 in the positive direction.
-
Move A1 in the positive direction, and then move A2 in the positive direction.
-
Move A1 in the positive direction, then move A2 in the positive direction, and then move A3 in the positive direction.
-
Move A1 in the positive direction, then move A2 in the positive direction, then move A3 in the positive direction, ……, and then AN in the positive direction.
Find the greatest coordinate occupied by the robot from the beginning to the end of the process.
Constraints
-
1≤N≤200000
-
−10^8≤Ai≤10^8
-
All values in input are integers.
Input
Input is given from Standard Input in the following format:
N A1A2A3…AN
Output
Print the greatest coordinate occupied by the robot from the beginning to the end of the process.
Sample Input 1
3 2 -1 -2
Sample Output 1
5
The robot moves as follows:
-
Move 2 in the positive direction, to coordinate 2.
-
Move 2 in the positive direction, to coordinate 4. Then move −1 in the positive direction, to coordinate 3.
-
Move 2 in the positive direction, to coordinate 5. Then move −1in the positive direction, to coordinate 4. Then move −2 in the positive direction, to coordinate 2.
The greatest coordinate occupied during the process is 5, so we should print 5.
Sample Input 2
5
-2 1 3 -1 -1
Sample Output 2
2
Sample Input 3
5
-1000 -1000 -1000 -1000 -1000
Sample Output 3
0
In this case, the initial coordinate 00 is the greatest coordinate occupied.
解题思路:题意很简单,先输入n表示执行n次操作,第二行输入每次操作的移动步数,机器人有两种走法,问你机器人在运行的过程中走到的最大的正方向的步数是多大
很明显是个模拟题机器人的每次移动都是从第1个指令运行到第i个指令,i从1到n,也就是总共会执行(n+1)*n/2次。看了下数据1e5直接T飞,这时候我们就要利用前缀和的关系
我们可以很容易的发现前缀和正好是机器人每次大循环的操作,这样我们就可以快乐的模拟了。
Code:
#include<cstdio> #include<algorithm> #include<cstring> #include<iostream> #define ll long long using namespace std; ll a[200005]; int main() { int n; scanf("%d",&n); ll sum=0,cnt=0,ans=0,mx=0; for(int i = 0; i < n; ++i) { scanf("%lld",&a[i]); } for(int i = 0; i < n; ++i) { sum += a[i];//表示的是a[i]的前缀和 mx = max(mx,sum);//更新最大的前缀和 ans = max(ans,cnt + mx);//每次更新 cnt += sum;//表示的是前缀和的前缀和 } printf("%lld ",ans); return 0; }