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

14 篇文章 0 订阅
4 篇文章 0 订阅


【题解】【乱搞】

【水题来袭!】

【先预处理出不添加元素时可以组成的"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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值