首页 > 代码库 > 【洛谷P1371】NOI元丹
【洛谷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£???oóμ? I 11 }N[L]; 12 struct fbx{ 13 int loc,i;//loc??oóμ? 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 }
【洛谷P1371】NOI元丹
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。