【洛谷P1371】NOI元丹

不考虑insert

则NOI的个数可通过O(n)递推得到:

sum_NOI<--sum_NO<--sum_N

考虑insert:

首先预处理对于每个N,其后面的O和I各有多少个

N:显然插入在最前面

I:最后面

O:枚举断点,前面的N*后面的I,取max

 1 #include<cstdio>
 2 #include<cstring>
 3 using namespace std;
 4 #define ll long long
 5 const int L=100100;
 6 int n,nn,ii,oo;
 7 ll ans,sum_N,sum_NO,sum_NOI;
 8 char s[L];
 9 struct fax{
10     int loc,o,i;//loc֮ǰµÄ O£¬Ö®ºóµÄ I  
11 }N[L];
12 struct fbx{
13     int loc,i;//locÖ®ºóµÄ I  
14 }O[L];
15 ll max(ll x,ll y){
16     return x>y?x:y;
17 }
18 void addN(){
19     ll n0=0;
20     for (int j=1;j<=oo;j++)
21         n0+=O[j].i;
22     ans=max(ans,sum_NOI+n0);
23 }
24 void addI(){
25     ll ooo,i0=0;
26     for (int i=1;i<=nn;i++){
27         ooo=N[i].o;
28         i0+=oo-ooo;
29     }
30     ans=max(ans,sum_NOI+i0);
31 }
32 void addO(){
33     ll o0=0;
34     for (int j=1;j<=nn;j++)
35         o0=max(o0,(ll)j*N[j].i);
36     ans=max(ans,sum_NOI+o0);
37 }
38 int main(){
39     sum_N=sum_NO=sum_NOI=ii=oo=nn=ans=0;
40     scanf("%d",&n);
41     scanf("%s",s);
42     for (int i=0;i<n;i++){
43         if (s[i]=='N'){
44             nn++;
45             N[nn].loc=i; 
46             N[nn].o=oo;
47             N[nn].i=ii;
48             sum_N++;
49         }
50         if (s[i]=='O'){
51             oo++;
52             O[oo].loc=i;
53             O[oo].i=ii;
54             sum_NO+=sum_N;
55         }
56         if (s[i]=='I'){
57             ii++;
58             sum_NOI+=sum_NO;
59         }
60     }
61     for (int j=1;j<=nn;j++)
62         N[j].i=ii-N[j].i;
63     for (int j=1;j<=oo;j++)
64         O[j].i=ii-O[j].i;
65     addN();
66     addO();
67     addI();
68     printf("%lld",ans);
69     return 0;
70 }
STD

 

转载于:https://www.cnblogs.com/Absolute-Zero/p/6012714.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值