4.22
1. codeforces #636(Div.3)C题:简单思维
题目大意:给一个序列,求最长交替子序列(先后顺序不变,正负交替)的最大和。
想法
输入的过程判断,flag记录前一个数的正负,pre记录前一个值;如果正负交替就更新sum,如果正负相同,sum-=,+=,记最大值。
出现问题:超时
修正:别人的代码;修改之后也超时,但是read()就不超时——我的代码read还是超时…
//超时代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 2e5+10;
ll read(){ll x; if(scanf("%lld",&x)==-1)exit(0); return x;}
int vis[maxn], dp[maxn], cntt[maxn];
//超时
//read()还是超时
int main(){
int t;
ll n, cnt = 0;
cin>>t;
ll flag = 0, pre = 0;
while(t--){
memset(dp, 0, sizeof(dp));
memset(vis, 0, sizeof(vis));
memset(cntt, 0, sizeof(cntt));
n = read();
cnt = 0;
ll sum = 0;
for(int i = 1; i <= n; i++){
vis[i] = read();
//cout<<1<<" "<<vis[i]<<endl;
if(i == 1){
cnt++;
pre= flag = vis[i];
cntt[i] = cnt;
sum+=vis[i];
//cout<<2<<" "<<vis[i]<<endl;
}
else if(flag*vis[i] < 0){
pre = flag = vis[i];
cnt++;
cntt[i] = cnt;
sum+=vis[i];
//cout<<3<<" "<<vis[i]<<endl;
}
else if(vis[i]>pre){
sum-=pre;
sum+=vis[i];
pre = vis[i];
cntt[i] = cnt;
//cout<<4<<" "<<vis[i]<<endl;
}
}
/*
for(int i = n; i >= 1; i--){
if(cntt[i] == cnt){
sum+=vis[i];
cnt--;
}
}
*/
printf("%lld\n", sum);
}
return 0;
}
思路:read()读入之后,依次遍历处理序列,m找到连续序列中最大值,等到正负交替(即序列交替时),sum+=m。
//AC代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 2e5+10;
ll read(){ll x; if(scanf("%lld",&x)==-1)exit(0); return x;}
int vis[maxn], dp[maxn], cntt[maxn];
//read(),解决超时问题
int main(){
int t;
ll n, cnt = 0;
cin>>t;
ll flag = 0, pre = 0;
while(t--){
n = read();
for(int i = 1; i <= n; i++){
vis[i] = read();
}
ll sum = 0;
int m = inf*(-1);
flag = abs(vis[1])/vis[1];
for(int i = 1; i <= n; i++){
if(vis[i]*flag>0){
m = max(m, vis[i]);
}
else{
flag = abs(vis[i])/vis[i];
sum+=m;
//cout<<" "<<m<<endl;
m = vis[i];
}
}
sum+=m;
printf("%lld\n", sum);
}
return 0;
}