T1:

小喵喵有 

现在小喵喵要吃掉一些小鱼干,出于一些原因,小喵喵会吃掉连续的一段区间中的所有小鱼干。

如果吃掉了 一段区间,那么小喵喵会获得一些满意度。

形式化地,总满意度 

由于只有小喵喵最喜欢的小鱼干的特殊度等于 

现在小喵喵可以选择任意一段区间(不能为空),但是有一些小鱼干的美味度是负数,吃掉所有小鱼干不一定会获得最多的满意度。所以小喵喵想知道最大能获得的总满意度是多少。

思路:

模拟+优化

首先可以想到n*n的模拟,但是复杂度过高于是我们想到:

可以在每个bi等于1的点预处理一个数组,表示这个点向左最大能延伸到多少

这样我们在枚举每个点的时候就只需要枚举在它之前有多少个bi为1的点就可以了

但是只是这样还是有问题的,如果最大值是不经过任何一个bi为1的点结果就是有问题的

所以我们需要再单独跑一遍判断

 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<cstring>
 6 #include<cstdlib>
 7 #include<set>
 8 #include<map>
 9 #include<vector>
10 #include<stack>
11 #include<queue>
12 #define ll long long
13 #define inf 2147383611
14 #define MAXN 101010
15 #define MOD
16 using namespace std;
17 inline ll read()
18 {
19     ll x=0,f=1;
20     char ch;ch=getchar();
21     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
22     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
23     return x*f;
24 }
25 ll n,a[MAXN],k[MAXN],cnt,sa[MAXN],b[MAXN],ans,m[MAXN],x;
26 int main()
27 {
28     n=read();
29     for(int i=1;i<=n;i++) {a[i]=read();sa[i]=sa[i-1]+a[i];}
30     for(int i=1;i<=n;i++) {x=read();b[i]=b[i-1]+x;if(x) k[++cnt]=i;}
31     k[0]=0,k[cnt+1]=n+1;
32     //for(int i=1;i<=cnt+1;i++) cout<<i<<" "<<k[i]<<endl;
33     ll tmp,_max;
34     memset(m,-127,sizeof(m));
35     for(int i=1;i<=cnt;i++)
36     {
37         tmp=0,_max=a[k[i]];
38         for(int j=k[i];j>k[i-1];j--)
39         {
40             tmp+=a[j];
41             if(tmp>=_max) {m[i]=j;_max=tmp;}
42         }
43     }
44     //for(int i=1;i<=cnt;i++) cout<<m[i]<<endl;
45     ll res;
46     if(b[1]) ans=sa[1]*b[1];
47     else ans=sa[1];
48     for(int i=1;i<=n;i++)
49     {
50         if(b[i]) ans=max(ans,sa[i]*b[i]);
51         else ans=max(sa[i],ans);
52         for(int j=b[i];j>=1;j--)
53         {
54             ans=max(ans,(sa[i]-sa[m[j]-1])*(b[i]-j+2));
55             //cout<<i<<" "<<j<<" "<<(sa[i]-sa[k[j]-1])*(b[i]-j+2)<<endl;
56         }
57     }
58     for(int i=1;i<=cnt+1;i++)
59     {
60         tmp=-inf;
61         for(int j=k[i-1]+1;j<k[i];j++)
62         {
63             if(tmp<0&&a[j]<=0) tmp=max(tmp,a[j]);
64             if(tmp>=0) tmp+=a[j];
65             if(tmp<0&&a[j]>0) tmp=a[j];
66             ans=max(ans,tmp);
67             //cout<<i<<" "<<j<<" "<<tmp<<endl;
68         }
69     }
70     printf("%lld",ans);
71 }
View Code

相关文章:

猜你喜欢
  • 2022-12-23
  • 2022-02-07
相关资源
相似解决方案