向前走莫回头❤

【洛谷 P1371】NOI元丹(枚举+乱搞)

【题解】【乱搞】

【水题来袭!】

【先预处理出不添加元素时可以组成的"NOI"的个数。N[i]表示正序计算到第i位'N'的个数,I[i]表示倒序计算到第i位'I'的个数。然后从前往后枚举‘O’,每次将N[i]*I[i]加入答案】

【然后,从前往后枚举在每个位置放'O'所多出来的方案数,或是当当前位置是‘O’时,在它前面多加一个'N'或在它后面多加一个'I'所多出来的方案数,在这三种情况中取最优值】

 

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
char s[100010];
int n,N[100010],I[100010],tot;
ll ans,maxn;
int main()
{
    int i,j;
    scanf("%d\n",&n);
    gets(s+1);
    for(i=1;i<=n;++i)
     if(s[i]=='N') N[i]=N[i-1]+1;
      else N[i]=N[i-1];
    for(i=n;i>0;--i)
     if(s[i]=='I') I[i]=I[i+1]+1;
      else I[i]=I[i+1];
    for(i=2;i<n;++i)
     if(s[i]=='O') ans+=(N[i]*I[i]);
    for(i=1;i<=n;++i)
      {
          ll s3=N[i]*I[i+1];
          maxn=max(s3,maxn);
      }
    ll s1=0,s2=0;
    for(i=1;i<=n;++i)
     if(s[i]=='O')  s1+=I[i];
    for(i=n;i>0;--i) 
     if(s[i]=='O')  s2+=N[i];
    s1=max(s1,s2); maxn=max(maxn,s1);
    printf("%lld\n",maxn+ans);
    return 0;
}



 

posted @ 2016-10-31 21:49  lris0-0  阅读(130)  评论(0编辑  收藏  举报
过去的终会化为美满的财富~o( =∩ω∩= )m